Fenix Eldritch Posted December 23, 2022 Share Posted December 23, 2022 (edited) Here's a very simple tool for looking at some basic info about an object's LinksetData store. It will report how many entries the datastore contains (both protected and non-protected) as well as the total size used in bytes. It can give a simplistic breakdown of how the size is allocated between KVPs and protected overhead. If the rumors of LL considering a form of GUI for LSD management turn out to be true, then this may become obsolete. But until then, maybe it'll be somewhat useful. /*************************************************\ Drop this script into an object and it will scan the LinksetData store if it exists and report some statistics. \*************************************************/ string tempKey = "LSD temporary byte count key"; //used to count the bytes of keys/values (28 bytes) default { state_entry() { integer tempA; //used for counting bytes integer tempB; //used for counting bytes integer LSD_MAX_SIZE = 65536; //current max is 64k integer countTotal = llLinksetDataCountKeys(); integer countProtect; integer bytesTotal = LSD_MAX_SIZE - llLinksetDataAvailable(); integer bytesPubKeys; integer bytesPrivKeys; integer bytesPubValues; integer largestRecordChr; integer largestKeyChr; integer smallestRecordChr = 0x7FFFFFFF; //init to max positive int integer smallestKeyChr = 0x7FFFFFFF; //init to max positive int integer largestRecordByte; integer largestKeyByte; integer smallestRecordByte = 0x7FFFFFFF; //init to max positive int integer smallestKeyByte = 0x7FFFFFFF; //init to max positive int integer i = countTotal; while (~--i) //this creates a range from count-1 to 0. Great for zero-indexed lists. { string currKey = llList2CSV(llLinksetDataListKeys(i,1)); string currData = llLinksetDataRead(currKey); //llOwnerSay((string)i+"|"+currKey+"|"+currData); //DEBUG llLinksetDataWrite(tempKey,currKey); //tempKey by itself is 28 bytes tempA = LSD_MAX_SIZE - llLinksetDataAvailable() - bytesTotal - 28; llLinksetDataWrite(tempKey,currData); //tempKey by itself is 28 bytes tempB = LSD_MAX_SIZE - llLinksetDataAvailable() - bytesTotal - 28; llLinksetDataDelete(tempKey); if(currData) //if data isn't empty, KVP was non protected { bytesPubKeys += tempA; //add to running key byte total if(tempA > largestKeyByte) //check if this is the biggest key so far { largestKeyByte = tempA; largestKeyChr = llStringLength(currKey); } if(tempA < smallestKeyByte) //check if this is the samllest key so far { smallestKeyByte = tempA; smallestKeyChr = llStringLength(currKey); } bytesPubValues += tempB; //add to running record byte total if(tempB > largestRecordByte) //check if this is the biggest record so far { largestRecordByte = tempB; largestRecordChr = llStringLength(currData); } if(tempB < smallestRecordByte) //check if this is the samllest record so far { smallestRecordByte = tempB; smallestRecordChr = llStringLength(currData); } } else //if data was empty, then the value was protected { countProtect++; bytesPrivKeys += tempA; if(tempA > largestKeyByte) //check if this is the biggest key so far { largestKeyByte = tempA; largestKeyChr = llStringLength(currKey); } if(tempA < smallestKeyByte) //check if this is the samllest key so far { smallestKeyByte = tempA; smallestKeyChr = llStringLength(currKey); } } } llOwnerSay("LinksetData statisitcs:" +"\n Total entries: "+(string)countTotal+" ("+(string)countProtect+" protected)" +"\n Total size: "+(string)(bytesTotal)+" out of 65536 bytes used" +"\n ├Public keys: "+(string)bytesPubKeys+" bytes" +"\n ├Public data: "+(string)bytesPubValues+" bytes" +"\n ├Protected keys: "+(string)bytesPrivKeys+" bytes" +"\n ├Protected data: "+(string)(bytesTotal - bytesPrivKeys - bytesPubValues - bytesPubKeys - (countProtect*32))+" bytes" +"\n └Protected overhead: "+(string)(countProtect*32)+" bytes" +"\n Largest key: "+(string)largestKeyByte+" bytes ("+(string)largestKeyChr+" characters)" +"\n Smallest key: "+(string)smallestKeyByte+" bytes ("+(string)smallestKeyChr+" characters)" +"\n Largest public data entry: "+(string)largestRecordByte+" bytes ("+(string)largestRecordChr+" characters)" +"\n Smallest public data entry: "+(string)smallestRecordByte+" bytes ("+(string)smallestRecordChr+" characters)" +"\nNOTE: each protected key:value pair adds 32 bytes to the datastore usage." ); } } Edited December 24, 2022 by Fenix Eldritch version 2 2 Link to comment Share on other sites More sharing options...
Fenix Eldritch Posted December 24, 2022 Author Share Posted December 24, 2022 Updated the OP with a new version. I realized I could further break down the byte counts with a single sacrificial LSD entry to measure key and value sizes. Although we can't read protected entries, knowing the other sizes and the protected overhead, we can infer how many bytes are being used for protected data entries. Link to comment Share on other sites More sharing options...
Quistess Alpha Posted December 24, 2022 Share Posted December 24, 2022 A minor bug for an empty datastore: Quote Largest key: 0 bytes (0 characters) Smallest key: 2147483647 bytes (2147483647 characters) Also, to make it fire after changes to the datastore (useful for rapid sanity-testing/debugging), you can swap to a different state so it doesn't interfere with itself: // code as above until: llOwnerSay("LinksetData statisitcs:" // ... ); state waiting; } } state waiting { linkset_data(integer action, string name, string value) { state default; } } 2 Link to comment Share on other sites More sharing options...
Fenix Eldritch Posted December 24, 2022 Author Share Posted December 24, 2022 17 minutes ago, Quistess Alpha said: A minor bug for an empty datastore Well shoot. And I'm past the edit window. Numerous ways to handle that, but a quick way would be to put something like this just before the final output: if(!countTotal) { smallestKeyChr = 0; smallestKeyByte = 0; smallestRecordChr = 0; smallestRecordByte = 0; } 2 Link to comment Share on other sites More sharing options...
Recommended Posts
Please take a moment to consider if this thread is worth bumping.
Please sign in to comment
You will be able to leave a comment after signing in
Sign In Now