Jump to content

irihapeti

Resident
  • Posts

    1,689
  • Joined

  • Last visited

Everything posted by irihapeti

  1. ++++++++++++++++ edit again: if you thinking of doing something like this in your LSL app then LepreKhaun made a mod (is post further down). Use that one bc is really good his mod ++++++++++++++++ edit: in response to feedback from revochen I recode this to the more formal coding style for the reasons raised. is post below ++++++++++++++++ this a script that came out of a chat about stuffing apples into a box in another post in the Library. This script about how many oranges can you stuff in the same box. Can stuff over 3300 oranges seems like if i had a question it would be have I missed anything else bugwise? // stores 3329 encoded keys losslessly in a string table // call this script with table id -3329 in num // llMessageLinked(LINK_THIS, -3329, "", yourkey); // return codes in num // 0 = table full // 1 = key found in table // 2 = key added to table // link_message(integer sender_num, integer num, string message, key id) // { llOwnerSay((string)num + " " + (string)id); } // //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ // // search code is Public Domain May 2014 by elizabeth (irihapeti) // // encoder is CCby3 license. as is based on some CCby3 works. refs: // Adam Wozniak and Doran Zemlja (public domain) // http://wiki.secondlife.com/wiki/Key_Compression // Becky Pippen (unspecified. assume CCby3) // http://wiki.secondlife.com/wiki/User:Becky_Pippen/Numeric_Storage // Combined Library (CCby3) // http://wiki.secondlife.com/wiki/Combined_Library // // CCby3 exception: you dont have to maintain credits for my contribution to the // encoder that you publish or distribute bc they Public Domain // // my encoder design contribution was to encode right-to-left so that decoding is // a little bit more straightforward to code for // //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ integer u = -3329; // table uniqueid. can change to whichever integer m = 3329; // max number of records. set lower if get stack/heap collisons string d; // data table integer c; // count of records in table default { link_message(integer n, integer b, string s, key k) { if (b != u) return; b = 0; if (c < m) { // encode s = llDumpList2String(llParseString2List((string)k, ["-"], []), ""); string e; integer i; for (i = 28; i >= 0; i -= 4) { n = (integer)("0x" + llGetSubString(s, i, i + 3)); b = (b << 1) | (n & 0x1); n = (n >> 1) & 0x7FFF; e += llBase64ToString(llIntegerToBase64( 0xE0808000 | (((n + 0x800) << 12) & 0xF000000) | (((n + 0x0800) << 10) & 0x3F0000) | ((n << 8) & 0x3F00))); } b = (b & 0xFF); e += llBase64ToString(llIntegerToBase64( 0xE0808000 | (((b + 0x800) << 12) & 0xF000000) | (((b + 0x0800) << 10) & 0x3F0000) | ((b << 8) & 0x3F00))); // search b = 0; i = llSubStringIndex(d, e); if (~i) { n = (i % 9); if (!n) jump y; i += (9 - n); n = llStringLength(d); @x; if (llGetSubString(d, i, i + 8) == e) jump y; if ((i += 9) < n) jump x; } d += e; c++; b++; @y; b++; } llMessageLinked(LINK_THIS, b, "", k); } }
  2. LepreKhaun wrote: irihapeti wrote: ty (: i fixed that one and the mask. well spotted. ty No, you made it worse. e += llBase64ToString(llIntegerToBase64( 0xE0808000 | (((n + 0x800) << 12) & 0xF00000) | (((n + 0x0800) << 10) & 0x3F0000) | (n & 0x3F00))); Should read: e += llBase64ToString(llIntegerToBase64( 0xE0808000 | (((n + 0x800) << 12) & 0xF000000) | (((n + 0x800) << 10) & 0x3F0000) | ((n << 8) & 0x3F00))); Otherwise, the last part is missing the bytes it should be masking. But as I said, this isn't the correct forum to practice in. OK? ty. my copypasta skills sux (: ok. i leave you alone now. i take my oranges and play in another post ty for the debugs as well (: ps. i still do like your 700+ version. is ideal for a library script i think
  3. ty (: i fixed that one and the mask. well spotted. ty
  4. edit more Leprekhaun point to bugs in this script. So ty to him for that (: I not fix this one anymore here. I just leave with the bugs in. Soooo.... DONT USE THIS SCRIPT IS BROKEN latest fixes version here: http://community.secondlife.com/t5/LSL-Scripting/3300-oranges/m-p/2706236#M23657 edit: i made some mod/opt to the oranges script i put here before. If anybody got that one already then delete and have this one if you want the other post script has a count flow error in it. so best not to use that one at all. bc counts the duplicates as well as the adds. I was testing that and forgot to change before post the main change I made was to the coding style of the search algo. i made all inline style bc is more consistent readability wise than to mix classic and inline coding styles in same code block as i was doing. I think anyways removed a unecessary int var, a else, and a modulus as well // store 3339 encoded keys losslessly// call this script with table id -3339 in num // llMessageLinked(LINK_THIS, -3339, "", yourkey);// return codes in num// 0 = table full// 1 = key found in table // 2 = key added to table // link_message(integer sender_num, integer num, string message, key id)// { llOwnerSay((string)num + " " + (string)id); } // // Public Domain May 2014 by elizabeth (irihapeti)// Base64 codes credit Strife Onizukastring d;integer c;default{ link_message(integer n, integer b, string s, key k) { if (b != -3339) return; b = 0; if (c < 3339) { // encode s = llDumpList2String(llParseString2List((string)k, ["-"], []), ""); string e; integer i; for (i = 28; i >= 0; i -= 4) { n = (integer)("0x" + llGetSubString(s, i, i + 3)); b = (b << 1) | (n & 0x1); n = (n >> 1) & 0x7FFF; e += llBase64ToString(llIntegerToBase64( 0xE0808000 | (((n + 0x800) << 12) & 0xF00000) | (((n + 0x0800) << 10) & 0x3F0000) | (n & 0x3F00))); } b = (b & 0xFF); e += llBase64ToString(llIntegerToBase64( 0xE0808000 | (((b + 0x800) << 12) & 0xF00000) | (((b + 0x0800) << 10) & 0x3F0000) | (b & 0x3F00))); // search b = 0; i = llSubStringIndex(d, e); if (~i) { n = (i % 9); if (!n) jump y; i += (9 - n); n = llStringLength(d); @x; if (llGetSubString(d, i, i + 8) == e) jump y; if ((i += 9) < n) jump x; } d += e; c++; b++; @y; b++; } llMessageLinked(LINK_THIS, b, "", k); } }
  5. LepreKhaun wrote: Absolutely fascinating. yw (: is there anything else I can help you with understanding?
  6. i just add to the discussion for people thinking about table/page/script ids in the linked forum post as i mention before is a technique of partitionning integer num into caller/callee pairs the idea being that a called/script can know who has called it. it use the form: num = (callerid << 16) | (calleeid); where caller and callee are uniqueids so caller goes: llLinkMessage(LINK_THIS, (myid << 16) | (calleeid), msg, id) callee goes: link_message(integer sender, integer num, string msg, key id) { if (num & 0xFFFF == myid) // then is for me whocalledme = (num >> 16) & 0xFFFF; + ok can partition this down further. for example if only have 256 scripts in app num = (myid << 8) | calleeid; this allows the top 16 bits for messages as well as string msg in the example encoded key table codes then can mod so tableid is some number less than 0xFF. where 0xFF is reserved for the Manager script if (!(b & 0xFF == myid)) return; whocalled = (num >> 8) & 0xFF; if whocalled is not on my list of valid callers then error do the encoding and search etc then pass message back to caller b = (returncode << 16) | (myid << 8) | whocalled; llLinkMessage(LINK_THIS, b, "", k); caller can then reverse to get the return codes. and can know which table return this result. So Manager can fire off lots of messages/tasks to lots of scripts and know when they complete and what is status of job complete. if fire a task then can know not to fire another task at a script until get message back
  7. LepreKhaun wrote: irihapeti wrote: i notice in the above header you refer to the encoder as a compression algo is not a compression. is an expansion. the set of all keys can be stored natively in 16 bytes per element. the key as we use/see in LSL is an expansion of this native element to 72 bytes. The encoder algo expands native to 18 bytes so is why is referred to as an encoder in the field of compression bc it it dont actual compress I'm uncertain how the word "compression" translates to your language but I was using it in its computer science definition, as did .Adam Wozniak and Doran Zemlja in their early implementation of this algorithm. Basically, not all encoding is compression but all compression is an encoding, if that makes sense. If your encoding wasn't a compression algorithm, you would've ended up storing the same number or fewer keys in the available memory. And, since more keys are stored and the original keys can be recovered from their compressed state, it is specifically a lossless compression. [ETA] There is an "expansion algorithm" there but that's what you're calling the decoder. It expands 9 UTF-16 characters back into the 32 UTF-16 characters (which are the original hexadecimal characters you compressed in the first place). Got it? i realise that people refer to this kinda algo as compression. Which is understandable when look at it in the most general sense in the field of compression is different classes of algos. compressors, packers and encoders is what I mean when say that this algo is not a compression algo. As it doesnt attempt to reach the entropic state of the ordinal set of inputs by exploiting commonalities that may be found in the inputs. it does the opposite. it dont try to reach the entropic state. it goes in the opposite direction algorithmically by design. Even tho space saving occurs. is a class of algo thingy this which makes sense to people who work in this field + can call this algo a packer tho. I never refer to it as a packer bc is not a very good one as wrote. So just refer to it as a encoder if was writing a packer then can losslessly encode 30 keys in 256 UTF chars. 17.067 bytes per. Instead of 18 bytes per as wrote if was writing a compressor then exploiting commonalities in keys, as well as the above. Order 0, 1, 2, etc + i have never looked closely at avatar keys myself in any exhaustive way, but I read once somewhere that one of the symbols near the middle (dont remember exactly now which one) is typically hex 0xF in many avatar keys. So that could be exploited for some bit savings. like for example if was 0xF 1/2 of the time then can gain approx. 31 bits for every 30 keys win some lose i also read some other time that the last bytes of keys seem to be generated by noise from the system clock in whole or part. Is not confirmed that just seems to be. if so can exploit that as well as a clock has known bounds. So can maybe get some gains in that area as well in a compressor this last two things are Order 0 techniques. If go to Order 1, 2, etc then might identity some other areas of commonality as well. Might maybe + if we ever were allowed access to the codes that LL do use to generate keys then could pretty probably easy compress to under 128bits per. The entropy being the ordinal set of the keys generated to date not that LL will ever ever let us see them codes. bc spoof. SL would get pretty messy for the residents in that situation
  8. i notice in the above header you refer to the encoder as a compression algo is not a compression. is an expansion. the set of all keys can be stored natively in 16 bytes per element. the key as we use/see in LSL is an expansion of this native element to 72 bytes. The encoder algo expands native to 18 bytes so is why is referred to as an encoder in the field of compression bc it it dont actual compress
  9. Dora Gustafson wrote: LSL is not at all suited for data base jobs weellll dunno about that (: has always been possible to create very large scale apps in LSL why people dont much do it is bc they get stuck on the asynch/synch problem when working with lots of scripts in the link to the other forum i put some codes that is a framework which show one way of dealing with this. i made as a page control system to help answer a question. It show tho how scripts can be used like subprograms/subroutines in a procedural way if use the same techniques then can make a pretty massive in-memory dB system just like you can in any language program -> dbManager script -> [1..n] table scripts in dBManager can manage it all. partitioning, hash table indexes, business rules, etc when have a dbManager then can add worker scripts to it as well. Like push/pull to webserver, etc in the codes I just posted here above just before. can see I am already doing in a dB way. by having a named table id i not write any dBManager harness tho. bc apples apparently (: for now anyways + can make all kinds of things this way. Like a game engine for example. program -> gameEngine -> gameBuffRebuff(s) -> dbManager not only can you do muli-script procedurals can also do parallel programing as well. a multi-dance ball is a parallel app for example. can also be applied to a dB or game engine that might have many many tables of unstructured data + ps. is some people do this already and been doing for years. but I think they think is a trade secret or something. Well is not now (:
  10. seeing as how you posting my own codes back at me. I suppose i better do some work now (: have inlined the encoding and put a table full flag in as well can squeeze in 1 or 2 more keys if mod more but i quite like 1661. dunno why just do (: // stores 1661 encoded keys in a table// call this script with table id -1661 in num // llMessageLinked(LINK_THIS, -1661, "", yourkey);// return codes in num// 0 = table full// 1 = key found in table // 2 = key added to table // link_message(integer sender_num, integer num, string message, key id)// { llOwnerSay((string)num + " " + (string)id); } list d;default{ link_message(integer n, integer b, string s, key k) { if (b != -1661) return; b = 0; if (llGetListLength(d) < 1661) { s = llDumpList2String(llParseString2List((string)k, ["-"], []), ""); string e; integer i; for (i = 28; i >= 0; i -= 4) { n = (integer)("0x" + llGetSubString(s, i, i + 3)); b = (b << 1) | (n & 0x1); n = (n >> 1); e += llBase64ToString(llIntegerToBase64( 0xE0808000 | (((n + 0x800) << 12) & 0xF000000) | (((n + 0x800) << 10) & 0x3F0000) | ((n << 8) & 0x3F00))); } e += llBase64ToString(llIntegerToBase64( 0xE0808000 | (((b + 0x800) << 12) & 0xF000000) | (((b + 0x800) << 10) & 0x3F0000) | ((b << 8) & 0x3F00))); b = !~llListFindList(d, [e]); if (b) d += [e]; b++; } llMessageLinked(LINK_THIS, b, "", k); } } edit: i made a typo in the codes. Should be < 1661 and not <= 1661. so i change to that
  11. what you will notice in the posted code is how the author is using hex notation for bitwise (& |) operands and using decimal notation for operands that use math operators (* /) can know from this that this code writer is a professional is sometimes tempting when first get into hex notation to go all hex. Can get really murky tho when start writing code like: 0x10 / 0xFF when 16 / 255 is a whole lot clearer. So follow the practice that this code writer has shown and you will be all good. Will save yourself a bunch of headaches as well (:
  12. LepreKhaun wrote: irihapeti wrote: 1642 keys for 65520 memory +/- however much bytecode the script uses more/less this than this gen script default{ touch_end(integer total_number) { integer k = 1642; list lst; string s; integer i; integer j; integer n; for (i = 0; i < k; i++) { for (j = 0; j < 9; j++) { n = (integer)llFrand(0x8000); s += llBase64ToString(llIntegerToBase64( 0xE0808000 | (((n + 0x800) << 12) & 0xF000000) | (((n + 0x800) << 10) & 0x3F0000) | ((n << 8) & 0x3F00))); } lst += [s]; s = ""; } llOwnerSay((string)llGetUsedMemory()); }} + a example key encoder/decoder can be found down in this chat for anybody who might want to play with such a thing http://www.sluniverse.com/php/vb/scripting/93810-quotation-marks-strings.html is public domain so can do whatever you want with it as you like + edit: i just correct the range in the gen script to be the same as the encoder script. it bump it up to a little bit to 1692 bc the range i had was overflowing on some randoms injecting extra spurious chars into the stream 1692 is right on the edge so in production codes then should have a way big margin for safety bc the memory allocation for LSL MONO is pretty unreliable seems like Very nice try but you're not working with a single key anywhere in your code, you're just storing 9 integers away in a string. You need the entire suite of subroutines as elizabeth wrote them to handle keys and Jopsy summed up the consequences of this approach quite well imo. And keep in mind that our programs carry memory overhead of it's own, one never has 64K of data storage. default{ state_entry() { llOwnerSay((string)llGetUsedMemory()); }} +/- for bytecode yes. i did mention that in the line above the codes yes ? + for people who might end up reading this the encoder/decoder linked to was designed to help with answering the questions - how to encode a key losslessly into a smaller space? - how to store encoded keys in logical groupings so that they can be extracted and decoded without loss - how can the storage method be implemented so is transportable to other storage medium? use cases other than OP wanting to transport to scripts and notecards (storage medium) is when transporting to a external website, packing into containers, etc. it only came into this thread when the discussion turn to what other formats can be used to store unique identifiers losslessly in this DB solution the discussion in this subthread is now about formats. Is not about the design of the DB solution itself. Which as I already said is pretty good. The lossy hash version is also pretty good when the probability loss margin is acceptable for your use case + anyone reading the link discussion can see that I actual agree with Jopsy and suggest an alternative coding approach to the problem confronting OP the problem being that OP was trying to jam everything into fewer scripts than the app requirements metrics actual allow. Which OP came to realise themself. So all good + i just make another observation about optimisation in the xorhash version for the readers. bc I am a modder (: if mod/move the hashing algo to the harness side then can pass to DB as integer. Can get a performance gain doing this, and can reduce further the bytecode size of the DB script by some amount. Is a transfer coding technique this. Transfer the bytecode space consumed to another memory block of the app where the space constraints are more relaxed. if also think about this a bit then can see how I would deal with the encoder bytesize issue in any mod I might do in a particular use case it may also be useful to know on the harness side what is the hash of a key for some other purpose. So if modding Leprekhaun's lossy DB solution for own purpose/use case then can think about this as well + in the general case then is not a biggie to not do the kind of opt/mod that I been chatting about !!! and.... important !!! opt/mod can obscure the purpose/intent of a general library solution. The purpose/intent of library is to provide a solution for the general case that can be easy used by others as is within its own bounds, and can be easy modded for specific use cases where those bounds need to be pushed/extended so take what I am chatting about with this in mind ok. me modder
  13. 1642 keys for 65520 memory +/- however much bytecode the script uses more/less this than this gen script default{ touch_end(integer total_number) { integer k = 1642; list lst; string s; integer i; integer j; integer n; for (i = 0; i < k; i++) { for (j = 0; j < 9; j++) { n = (integer)llFrand(0x8000); s += llBase64ToString(llIntegerToBase64( 0xE0808000 | (((n + 0x800) << 12) & 0xF000000) | (((n + 0x800) << 10) & 0x3F0000) | ((n << 8) & 0x3F00))); } lst += [s]; s = ""; } llOwnerSay((string)llGetUsedMemory()); }} + a example key encoder/decoder can be found down in this chat for anybody who might want to play with such a thing http://www.sluniverse.com/php/vb/scripting/93810-quotation-marks-strings.html is public domain so can do whatever you want with it as you like + edit: i just correct the range in the gen script to be the same as the encoder script. it bump it up to a little bit to 1692 bc the range i had was overflowing on some randoms injecting extra spurious chars into the stream 1692 is right on the edge so in production codes then should have a way big margin for safety bc the memory allocation for LSL MONO is pretty unreliable seems like
  14. (: thinking about what the value being operated on by an operand, opens up a world of discovery and possibilities. Adventure even (: consider something a little more simple. A 3 bit binary string. In 3 bits can store 8 values. 0 to 7. In binary: 0 = 000 1 = 001 2 = 010 3 = 011 4 = 100 5 = 101 6 = 110 7 = 111 the rightmost bit is the 1 column. Middle bit is the 2 column. Left bit the 4 column. When extend this left then the column value doubles. 4 bits 8. 5 bits 16. 6 bits 32. etc back to the 3 bits. What happens if AND 1. AND 1 evaluates the rightmost bit. 0 & 1 = 0. 1 & 1 = 1 0 000 & 1 = 0 1 001 & 1 = 1 2 010 & 1 = 0 3 011 & 1 = 1 4 100 & 1 = 0 5 101 & 1 = 1 6 110 & 1 = 0 7 111 & 1 = 1 can see from this that all even numbers evaluate to 0. all odd numbers evaluate to 1 code example: if (n & 1) {then n is odd} else {n is even} + ok. next. what can we learn about n when AND 4. 4 in binary is 100. So we now evaluating the value of n based on the 4 column bit if (n & 4) {then n is ?} else {n is ?} yes. n is either high or low + this the adventure. While AND is often used to evaluate as TRUE or FALSE. It can also be used to discover ODD or EVEN. HIGH or LOW and other things. Like what do we get if AND 2? we get 2 numbers that are low, of which one is odd and the other even. And also get 2 high numbers. one odd. one even. We now starting to think about them as sets [2,3,6,7] [0,1,4,5] + to experiment with learning about this can write a test loop. Something like: integer top = 7; // or higher as you like integer n; for (n = 0; n <= top; n++) { if (n & 1) llOwnerSay((string(n) + " n&1 = " + (string)(n & 1)); if (n | 2) llOwnerSay((string(n) + "n|2 = " + (string)(n | 2)); // ... etc } + the OR (|) operator also need to be proficient with. Can think of it like bitwise addition. Refer the binary table above n = 2 | 1. set the 2 bit and the 1 bit. n = 3 n = 4 | 2. (n=6) where this gets really useful is with stuff like: MOVE = 1; FAST = 2; ZOOM = 4; m = MOVE; m = m | FAST; m = m | ZOOM; we doing bitwise addition to go faster if (m == (MOVE | FAST | ZOOM)) { brmmm! woohoo! } else if (m == (MOVE | FAST)) { shout go faster! } else if (m == MOVE) { blinking snail lol } else if (!m) { aww man! goooooooo ok !!! } else { o.m.g !!! you broke it. get off quick!! before somebody comes (: } + once you comfortable with AND OR NOT (& | !) then you be a long way down the road to where you want to be then can tackle things like (~) (<<) (>>) etc. Once get into these then will be getting way down into bitwise math and logic programming techniques. So learn the 3 commons (& | !) bc without them then the more deeper stuff isnt going to make much sense also bc the commons are used in heaps of LSL code examples and scripts. And also bc many LSL functions use bitsets as parameters
  15. according to the wiki entry you linked to below then (in MONO) a 9-char UTF16 string consumes 36 bytes when stored in a list (any length string carries fixed overhead of 18 bytes apparently) . a key as string consumes 90. So 2.5x not 3x by equivalence for the approximation (guesstimate) then 700 x 2.5 = 1,750
  16. 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
  17. you on it (: ok. time to move up. AND operator (&) whats happens: if (count & 4) + eta: think about what is the value of count when (count % 4) is true and when is false then think about the value of count when (count & 4) to help you get started. I do the table for % 0 % 4 = 0 1 % 4 = 1 2 % 4 = 2 3 % 4 = 3 4 % 4 = 0 5 % 4 = 1 6 % 4 = 2 7 % 4 = 3 8 % 4 = 0 do the table for & and see what you get
  18. LepreKhaun wrote: 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). can understand the wider point you making. just that like my train driving i have history in going brrmmm!!! is not a biggie but I do again so not to make a hash of it this time. jejeje (: is this code: string str = (string)id;str = llDumpList2String(llParseStringKeepNulls((str = "") + str, ["-"], []), ""); 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)); is opt code string str = (string)id;integer xorHash = (integer)("0x" + llGetSubString(str, 0, 7)) ^ (integer)("0x" + llGetSubString(str, 9, 12) + llGetSubString(str, 14, 17)) ^ (integer)("0x" + llGetSubString(str, 19, 22) + llGetSubString(str, 24, 27)) ^ (integer)("0x" + llGetSubString(str, 28, -1)); + i also just say that both versions of your key DB solution are pretty good. Lots of people will find good use for them. So thats good
  19. LepreKhaun wrote: But this has gotten seriously off topic. true (: altho in my defense. it went off topic bc you put a probabilty number out there and I went hmm! dont think thats quite right not in my defense tho is that I have history as a not very good train driver. Can derail anything me bc I am nosey (:
  20. LepreKhaun wrote: [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. we now moving on the same path so thats good yes. was the 8,589,934,591? that threw me 1 / 0.0000000001164153218 = 1 in 8589934594. Is the probability this of collision of 2 numbers drawn randomly from 4294967296 + is the xorhash algo that causes the collisions by pigeon hole. is of the form 128 % 32. Proof by counter example: stuffing unique numbers (128bit avatar keys) into a list will never cause a collision need to factor this in when determining the collision probability in this case
  21. 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
  22. 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
  23. 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
  24. you on a good path bc you want to improve your skills/knowledge which is always a good thing (: in the codes you posted are these: if (count % 2 == 0) if (count % 2 != 0) as a exercise think about how these might be re-written for example the NOT operator (!) what happens when write them as: if (count % 2) if (!(count % 2)) and think about how/why does this work as it does the why of things sometimes eludes us when starting out with bitwise. We just do and it works (: Dunno why sometimes. Just that it does. But after a while then it starts to make sense You on the right path tho I think. Can learn heaps doing what you already doing. Get a script written by expert/experienced person and play with it
  25. i think that the best place to start is knowing what the operators are and how to use them Is a table that show this here: http://wiki.secondlife.com/wiki/LSL_Operators
×
×
  • Create New...