Jump to content

LepreKhaun

Resident
  • Posts

    1,384
  • Joined

  • Last visited

Everything posted by LepreKhaun

  1. Interesting idea. I know of no literature that covers the average length of avastar names but if it was only 14 characters, one would get 1,388 of them stored. That's due to the fact that strings carry a set overhead, regardless of their length. Integers are much more friendly in lists.
  2. irihapeti wrote: Dora Gustafson wrote: With danger to confuse the issue seeing as how you taken over driving the train and I am only the passenger now then (: can encode the keys into 18 bytes loselessly. so no collisions. (18bytes = 9 UTF16 chars. which is 2 more than native key of 16bytes) as a guesstimate then if 64byte (32 UTF16 chars) strings = 700 approx. capacity. then about 3x something Unsure what place a "guesstimate" has within LSL. The code is already written, just write your algorithm in place of mine and see what results. I, for one, would be very interested to hear the results.
  3. irihapeti wrote: can maybe get a little performance gain by picking direct from str. example integer xorHash = (integer)("0x" + llGetSubString(str, 0, 7)) ^ (integer)("0x" + llGetSubString(str, 8, 11) + llGetSubString(str, 12, 15)) ^ (integer)("0x" + llGetSubString(str, 16, 19) + llGetSubString(str, 20, 23)) ^ (integer)("0x" + llGetSubString(str, 24, -1)); havent tested it tho so only maybe eta: sorry the offsets wrong. should be 9,12. 14,17. etc Though that's certainly is "making a hash of it", I don't think that's quite what Sassy had in mind. :smileyvery-happy: Seriously, this type of attempted optimization may be of benefit in tightening up a closed loop (such as a longish for() or while() construction) but when it comes to link messages, the message transport itself is the bottleneck. My experiments seem to point to a lower limit of 3 server frames (app. 0.066s) for an entire request & response sequence. Database manipulations in a shared use environment simply aren't going to be "time is of the essence". Better to write concise, understandable and modular code and focus on memory footprint (the smaller the code size of your DBM, the more storage for data available).
  4. The algorithm used for hash making only contributes its entropy. In other words, the less random it is, the greater the chance of collision. Otherwise, it is just the two factors I mentioned earlier, the number of hash buckets available and the number of objects you're assigning to them. My XOR algorithm is simply cramming 128 bits of information into a 32 bit space, there's other ways to do that but that's unimportant. Any and all hashing algorithms suffer from the Birthday Paradox- the point is the steepness of the curve at the lower end, the chances of a collision rises very rapidly at first as the number of objects are increased. The "gotcha!" is that smaller hash sizes allow more storage in the same space which ends up compounding the effect. But this has gotten seriously off topic. Let's just leave it where hashes are not the way to go unless one has seriously studied the subject, know the risks involved and can make an informed decision on whether or not they're worth taking. As it is, there are much better approaches to the problem available to one in LSL, if simply because the original key cannot be recreated from its hash element (perhaps you'd like to IM all those avatar keys you have stored to date).
  5. I have have no disagreement with any of that. A judgment call based on one's opinion is different than a general rule based on facts though, which is all I was pointing out.
  6. WARNING: Path is is through a thorny thicket from this point on...
  7. irihapeti wrote: i do again using wikipedia example. (is the same as i did before but this time i use their formula notation) (n*n) / (2*m) where n = 3874 and m = 4294967296 (3874 * 3874) / (2 * 4294967296) 15007876 / 8589934592 = 0.00174715 + ok if is just 1 value in the list and add a 2nd one then n = 1 (1 * 1) / (2 * 4294967296) 1 / 8589934592 = 0.0000000001164153218 which is what you show + i think what caused me to be puzzled is that this formula approximates the probability of 2 or more identical values in [0..4294967295] randomly-drawn appearing in the sets [2] .. [3874] which is not what we want to know. We want to know: how many collisions will occur when reduce the set of all 128bit keys down to 32bit hashes? in practice tho, there has been nearly 40 million avatar keys issued. The question then becomes: How many of these keys will collide when hashed? approx. upperbound: 40000000 / 4294967296 = 0.009313226 of this number how many will potentially be added to the list. 0.009313226 / 3874 = 0.0000024040 1 in 415,967 approx. chance of collision. Assuming that the generation of avatar keys is truly random (which it isnt but close enough) can lift this further if assume the potential addees is way less than 40 million. like 10,000,000 say. then 10000000 / 4294967296 / 3874 = 1 in 1,663,870 so pretty good odds i think Mmm, you've assumed the size of the set of 128 bit keys has some influence on this. It doesn't. If one has 23 people in the same room, there is a 50% probability that two of them have the same birthday. And that would be true if there were only 23 people in the entire world or over 23 billion. In other words, the only two factors to consider are the number of bins (365 in this case) and how many you've dropped into them (23) but how big the bag is your pulling from has no bearing on the results. Unless, of course, it empties out at some point. [ETA...] It doesn't matter how the 32 bit hashes are arrived at, there are only 8,589,934,591 [Oops, I was off by a factor of two! LOL] 4,294,967,295 bins available. If you randomly placed nearly 4,000 objects (which is less than one millionth of the size of available bins, I'll point out) into those bins, one might assume the chances were "incredibly small" for two to occupy the same bin (collide). But the fact is, if you sold only 10,000 units relying on such, you'd most likely have around a dozen extremely irate customers. Not a very good approach to staying in business.
  8. irihapeti wrote: LepreKhaun wrote: [ ETA: Trivia bit- 820,000,000,000 of our 128-bit UUID keys have a risk of 0.0000000001% of colliding. Now THAT is what I call an incredibly small chance!] have been puzzling over this as am not sure how you calc this as by pigeonhole pow(2,128) / pow(2,32) = pow(2,96) pow(2,96) keys will have the same pow(2,32) hashcode simplify pow(2,4) / pow(2,1) 4 / 1 xor table 0 1 2 3 1 0 3 2 2 3 0 1 3 2 1 0 + if assume that no persons with same xorhash do use the device within the same period then by approximation: pow(k,2) / (2 * pow(2,32)) where k = 3874. then collision is about 1 in 600 if factor in pigeonhole then 1 in 150 about + or i might be missing something else altogether. is why i am a bit puzzled I just used the table I linked to in that fascinating read on a little-understood subject. Just go down the #bits column to 128 (which is what a UUID key uses) and then come out across. But the article itself explains how the table is derived and I'll just leave it at that. I can't explain the paradox any better than it does. It is counter-intuitive though and has bitten many a person unaware of it. Hashes can be somewhat tricky that way...
  9. Qie Niangao wrote: ... it's generally okay to just keep one listener open forever, rather than managing a fresh one each time a dialog is raised. ... You can have that opinion. But until someone can prove listens don't consume server resources, my attitude regarding them is the same as I have for the lights in my home: Turn 'em on when needed, off when done.
  10. Sassy Romano wrote: If you need to store a LOT more, then you can accomplish this by first performing a hash of the UUID and then push a part of this to the list to store.. The chance of collision will be incredibly small and as long as that's not going to prove to be a statistically important issue, then you can store thousands of unique users. Ahhh, I like! Though that does raise the Birthday Paradox (where the possibilty isn't as small as one might think and Murphy's Law should always be considered in these things!) as well as precluding any further development that would require a lossless compression that I used to begin with. // "Store 700+ Unique UUIDs In World" by LepreKhaun 4/18/2014// Modified 4/23/2014 using the suggestion of// Sassy Romano (thank you!) to use a hashing algorithm//// This version will store ***3,784*** keys! // BUT with a probability greater than 0.1% of a collision// (meaning- every so often, a key will be falsely said to be found).//// See http://community.secondlife.com/t5/LSL-Library/Store-700-Unique-UUIDs-In-World/td-p/2669408 for usage// May be freely used, modified and distributed ONLY with this header intact!//list keysStored;default{ link_message(integer sender_num, integer num, string str, key id) { if (~num) // abort unless num != -1 return; // delete hyphens from key string str = (string)id; str = llDumpList2String(llParseStringKeepNulls((str = "") + str, ["-"], []), ""); // form 4 integers from key and XOR them together into one integer xorHash=(integer)("0x" + llGetSubString(str, 0, 7)) ^ (integer)("0x" + llGetSubString(str, 8, 15)) ^ (integer)("0x" + llGetSubString(str, 16, 23)) ^ (integer)("0x" + llGetSubString(str, 24, -1)); // see if the key is in list if(~llListFindList(keysStored, [xorHash])) { // it was found llMessageLinked(LINK_THIS, TRUE, "", id); } else { // it was not found, so // store it first keysStored += [xorHash]; llMessageLinked(LINK_THIS, FALSE, "", id); } }} [ ETA: Trivia bit- 820,000,000,000 of our 128-bit UUID keys have a risk of 0.0000000001% of colliding. Now THAT is what I call an incredibly small chance!]
  11. Let's see, in the past year or so, we know of: A leaving of many old-time Lindens, including the CEO. A diminishing user base resulting in a smaller revenue stream. Acquisition and production of new properties (Blocksworld, Patterns, Desura and "More Coming Soon!") The integration of commercial ads into here (a site that is rated well within the top 4000 in the world btw). A change of the ToS giving LL the rights as discussed. [ETA] Integration into social media sites such as FaceBook. Hmmmm, maybe SL is being coveted by Bill Gates, eh?
  12. In Blender, you set your faces with material assignments; each different material will result in another face in your uploaded mesh (up to a maximum of 8 for each mesh object). The order of the materials will directly correspond with the face numbers in Second Life (with the first material used being face 0, the second face 1 etc). As an added bonus, the faces you make don't have to be contiguous. In other words, you can have a specific face appear in different areas of your mesh. Also, when doing your UV mapping, each material can overlap the others in UV space, since they are being textured separately in SL.
  13. always a pleasure... Here's a tighter script. The following changes were made: Made ToucherID a local variable to the touch_start() event handler. No need to have it global. Dropped the timer setting down to 10 seconds. A full minute is way too long for such an easy choice. Reformatted the button choices for a better appearance. Redid the if() testing in listen(). Just need to check for correct answer, anything else is wrong. list buttons = ["Humans", "Assamite", "Governor", "-", "Zane", "-"];string dialogInfo = "\nWho are the judges of Caine's children of Abel?";integer dialogChannel;integer listenHandle;default{ state_entry() { dialogChannel = -1 - (integer)("0x" + llGetSubString( (string)llGetKey(), -7, -1) ); } touch_start(integer num_detected) { key ToucherID = llDetectedKey(0); llListenRemove(listenHandle); listenHandle = llListen(dialogChannel, "", ToucherID, ""); llDialog(ToucherID, dialogInfo, buttons, dialogChannel); llSetTimerEvent(10.0); // Here we set a time limit for responses } listen(integer channel, string name, key id, string message) { llListenRemove(listenHandle); // stop timer since the menu was clicked llSetTimerEvent(0); if (message == "Assamite") { llGiveInventory(id, "zv egg"); } else { llWhisper(0, "The RiddleBunny smashes your easteregg overtop your head and tells you to try again."); } } timer() { // stop timer llSetTimerEvent(0); llListenRemove(listenHandle); llWhisper(0, "Sorry. You snooze; you lose."); }}
  14. The call to llDetectedKey() only works in certain event handlers (see Specification for details). Change the line that reads "llGiveInventory(llDetectedKey(0), "zv egg");" to "llGiveInventory(id, "zv egg");"
  15. I beleive any linkage is OK, as long as it's on-topic and (of course!) not to explicit adult material or such.
  16. The bitwise NOT ("~") operator can be somewhat confusing until you realize one important point (well, two actually. LOL). The result of ~(-1) is 0, all other numbers result in non-zero when the NOT operator is applied to it. Zero is always (within LSL comparisons) interpreted as FALSE and any non-zero value as TRUE. So, whenever you see a library function that returns a minus one (-1) as one of it's values (usually a "not found" or "out of bounds" condition), you can apply the bitwise NOT operator to its return in a conditional test (such as if() or while()). This is one of the few shortcuts that is both faster and takes less memory than any other approach.
  17. Laurent Bechir wrote: Could you give me the url of this post, please ? I've searched with "Lost out of a Sim" in the forums, and I haven't found anything. I also haven't found anyone with the name of miranda Thank you http://www.sluniverse.com/php/vb/scripting/94577-lost-out-sim.html#post1934011
  18. arton Rotaru wrote: ... You may also want to limit how many objects a single avatar can take, by storing the avatars UUID in a list. No sooner said than done.
  19. This is a simple, subordinate database storage program for a single prim object. As written it will store approximately 745 unique keys (when saved under Mono!) as well as alerting the calling program of an attempt to store a duplicated key in the data store. This would be useful for "One per Customer" offerings, "One User, One Vote", and such. Usage is straight forward, llMessageLinked(LINK_THIS, -1, "", keyToBeStored); in the main program to check for duplication and store the key if not already in the key list. If already in list, the program sends a llMessageLinked(LINK_THIS, TRUE, "", id); ( where "id" is "keyToBeStored", so a global isn't required in the main program to keep track of this), otherwise, it stores the key and sends a llMessageLinked(LINK_THIS, FALSE, "", id); back. See the following example Harness Test script for exactly how this is used. // "Store 700+ Unique UUIDs In World" by LepreKhaun 4/18/2014 // // See http://community.secondlife.com/t5/LSL-Library/Store-700-Unique-UUIDs-In-World/td-p/2669408 for usage // May be freely used, modified and distributed ONLY with this header intact! list keysStored; default { link_message(integer sender_num, integer num, string str, key id) { if (~num) // abort unless num != -1 return; // delete hyphens from key string str = (string)id; string shortKey = llDumpList2String(llParseStringKeepNulls((str = "") + str, ["-"], []), ""); // see if the key is in list if(~llListFindList(keysStored, [shortKey])) { // it was found llMessageLinked(LINK_THIS, TRUE, "", id); } else { // it was not found, so // store it first keysStored += [shortKey]; llMessageLinked(LINK_THIS, FALSE, "", id); } } } This Harness Test script illustrates how "Store 700+ Unique UUIDs In World" is called and how the response can be handled. The touch_end() event handler starts an extended loop that continues in the llMessageLinked() calls within link_message(). This loop is set to stop when "Store ..." either hits a stack-heap error collision at 745 entries, or when a duplicated key is entered into the database. The second result is very unlikely using llGenerateKey() so there is a section one may uncomment to force a duplication after 100 entries. // Main program "Harness Test" by LepreKhaun 4/18/2014 // for "Store 700+ Unique UUIDs In World" // // See http://community.secondlife.com/t5/LSL-Library/Store-700-Unique-UUIDs-In-World/td-p/2669408 for usage // May be freely used, modified and distributed ONLY with this header intact! integer counter; key newKey; default { touch_end(integer num) { llMessageLinked(LINK_THIS, -1, "", llGenerateKey()); } link_message(integer sender_num, integer num, string str, key id) { // increment counter and check for near capacity if(counter == 700) { llInstantMessage(llGetOwner(), "Warning Storage is at 700 keys!"); } if(~num) // ignore if num == -1, we sent the message { if(num) { // The key was already in list llOwnerSay("Oh, Noooo!!! Duplicated Key!\n" + (string)id); } else { // The key was not in list but has been added llOwnerSay("Key #" + (string)(++counter) + " ==\n" + (string)id); // comment next if statement for maximum storage test // otherwise, remove "//" for duplicate key reaction // if (counter != 100) newKey = llGenerateKey(); llMessageLinked(LINK_THIS, -1, "", newKey); } } } } NOTES: Since both scripts are in the same prim, they both can "hear" their own link messages, so a means must be in place to differentiate between them. In this case, I am using "integer num", the second parameter of both llMessageLinked() and link_message(), and taking advantage of the fact that a bitwise NOT applied to -1 results in 0 (refer to usage of "if(~num){}" in both programs). There are other schemes one can use for this.For maximum storage, the 4 hyphens are stripped from each key before being stored as a string in the global list "keysStored". I've found only one other storage method that enables one to store more than this (by translating a key into a list of 4 integers), however the complexity of the supporting functions to handle this method precludes any easily modified versions.For repeated testing of the two scripts, both must be reset; one so the global list can be cleared, the other so that "counter" can be reset to 0.It might be noted that after about 300 iterations, the counter numbers appearing in chat will lose coherency and no longer appear in order. This is expected behavior and only another way of showing that LSL is asynchronous, always.For storage of much more than 700 UUID keys, off world storage should be considered.As always, any questions, comments, suggestions, corrections and constructive criticisms are welcome and appreciated. [Edited for minor grammar corrections. Nit picking up to the last!]
  20. Though your efforts to get an explicit clarification from LL is laudable, I feel it misses the mark. The ToS, copyrights and content licensing all fall under contract law and, lacking ambiguity in their construction, the Four Corners Rule will always be used in disputes. In other words, it matters not whether an employee of LL said "Yes" or "No", if the ToS lacks ambiguity, the ToS would stand as written. The current ToS reads plainly to me. I see no ambiguity there and I see no ambiguity in CC BY 4.0 either. By the same token, I do see a square peg and a round hole- I fail to see any compatibility between the two outside of an explicit CC0 (see Section 2a.5 for what I base my belief on). So, since the current Terms of Service for Second Life plainly states the intention of Linden Lab to claim "the non-exclusive, unrestricted, unconditional, unlimited, worldwide, irrevocable, perpetual, and cost-free right and license to use, copy, record, distribute, reproduce, disclose, sell, re-sell, sublicense (through multiple levels), modify, display, publicly perform, transmit, publish, broadcast, translate, make derivative works of, and otherwise exploit in any manner whatsoever, all or any portion of your User Content (and derivative works thereof), for any purpose whatsoever in all formats, on or through any media, software, formula, or medium now known or hereafter developed, and with any technology or devices now known or hereafter developed, and to advertise, market, and promote the same." and it is generally recognized that this is an overly broad and unfair claim to our creative contributions, I feel efforts should be made to have Linden Lab roll back their ToS to a much friendlier construction than to ask for any "clarification" which would stand outside of the Four Corners of the contract.
  21. Gregory McLeod wrote: ... Can the messages about the primname owner and its location be removed? No, if that was possible then IM could be used as a griefing tool, with no way to determine directly what it was flooding your e-mail inbox.
  22. What's happening is a and b are forming a convex curve during smoothing but c and d are concave. To correct: I'd remove d and extend the end of b to where d ended. This will erase the transition between b and d you now have but it may not still look right because you're asking Blender to make some complex calculations at the abc corner. You may have to add a hidden plane to extend the end of a under c and separate smoothing groups here to get it right.
  23. For anyone with a premium home that is feeling creative, there is a free texture pack for each of the four styles. Each texture pack has dozens of patterns that are specific to its style, making any interior additions you do fit in perfectly. To get these, go to the telehub for the area, they'll be available in a L$0 vendor off to the side. All the telehubs show on the world map except for Merlyn's, making that one a magical quest to find. [HINT: Look for the large structure that doesn't fit into the general plan.]
  24. Dora Gustafson wrote: ...One person can open several handlers before that happens ... Dora, if someone is wanting to click on "several" dance balls within 20 seconds while ignoring the dialog menus popping up on their screen, then they don't need a dance animation anyway- They need to learn how to interact with objects in Second Life. :smileytongue: I do apologize to the others for allowing allowing myself to be pulled into a mean-spirited game. I should've realised from the outset what was happening and just ignored it. Getting back on topic, many of the older scripts do not handle listeners properly. The original script example given by the OP and the problem it presented is typical of the time period before scripters found ways to open listen handles when needed and close them when they were no longer required. That practice is to be recommended and I hope my rewrite shows how an older script can be upgraded to follow it.
×
×
  • Create New...