Welcome to the Second Life Forums Archive

These forums are CLOSED. Please visit the new forums HERE

LIBRARY: reverse Find, and reverse order Functions

Void Singer
Int vSelf = Sing(void);
Join date: 24 Sep 2005
Posts: 6,973
06-19-2009 13:25
so I was needing to find the last instance of a search item for strings and lists, and decided that looping through every element was slow for large inputs, so I threw these together.... just some drop in functions that do what the LLfunctions don't...

UDPATED:2009 June 21 (happy Fathers Day to the dads out there)

CODE
/*//-- Get Last Index of String Test in String Source --//*/

integer uGetStrIdxRev( string vStrSrc, string vStrTst ){
integer vIdxFnd =
llStringLength( vStrSrc ) -
llStringLength( vStrTst ) -
llStringLength(
llList2String(
llParseStringKeepNulls( vStrSrc, (list)vStrTst, [] ),
-1)
);
return (vIdxFnd | (vIdxFnd >> 31));
}


CODE
/*//-- Get Last Index of List Test in List Source --//*/

integer uGetLstIdxRev( list vLstSrc, list vLstTst ){
integer vIdxFnd =
(vLstSrc != []) +
([] != vLstTst) +
([] != llParseString2List(
llList2String(
llParseStringKeepNulls(
llDumpList2String( vLstSrc, ";" ),
(list)llDumpList2String( vLstTst, ";" ),
[] ),
-1 ),
(list)";",
[] ));
return (vIdxFnd | (vIdxFnd >> 31));
}

NOTE: uGetLstIdxRev only works for string data types, and you may want to modify the separator to suit your needs (it should be something that WON'T be in any of the data)

CODE
/*//-- Reverse List Order (fast version) --//*/

list uListRevF( list vLstSrc ){
integer vIntCnt = (vLstSrc != []);
@Loop; if (vIntCnt--){
vLstSrc += llList2List( vLstSrc, vIntCnt, vIntCnt );
jump Loop;
}
return llList2List( vLstSrc, (vLstSrc != []) >> 1, -1 );
}


CODE
/*//-- Reverse List Order (small version) --//*/

list uListRevS( list vLstSrc ){
integer vIntCnt = (vLstSrc != []);
@Loop; if (vIntCnt--){
vLstSrc += llList2List( vLstSrc, vIntCnt, vIntCnt );
vLstSrc = llDeleteSubList( vLstSrc, vIntCnt, vIntCnt );
jump Loop;
}
return vLstSrc;
}


CODE
/*//-- Reverse String Order (fast version) --//*/

string uStringRevF( string vStrSrc ){
integer vIntCnt = llStringLength( vStrSrc );
@Loop; if (vIntCnt--){
vStrSrc += llGetSubString( vStrSrc, vIntCnt, vIntCnt );
jump Loop;
}
return llGetSubString( vStrSrc, llStringLength( vStrSrc ) >> 1, -1 );
}


CODE
/*//-- Reverse String Order (small version) --//*/

string uStringRevS( string vStrSrc ){
integer vIntCnt = llStringLength( vStrSrc );
@Loop; if (vIntCnt--){
vStrSrc += llGetSubString( vStrSrc, vIntCnt, vIntCnt );
vStrSrc = llDeleteSubString( vStrSrc, vIntCnt, vIntCnt );
jump Loop;
}
return vStrSrc;
}


the fast versions run at ~double the size, and aren't so much faster (they compile smaller actually), the small versions run a hair slower, but use less memory while running (and compile slightly larger)

all optimized with help from Strife Onizuka (thanks)
_____________________
|
| . "Cat-Like Typing Detected"
| . This post may contain errors in logic, spelling, and
| . grammar known to the SL populace to cause confusion
|
| - Please Use PHP tags when posting scripts/code, Thanks.
| - Can't See PHP or URL Tags Correctly? Check Out This Link...
| -
Strife Onizuka
Moonchild
Join date: 3 Mar 2004
Posts: 5,887
06-20-2009 22:39
From: Void Singer
none of them are double checked for optimizations... so there may be some tweaks to speed them up


Now they have. ^_^

I liked how you reused the last element in the fast versions of the reverse. I thought it was a mistake at first. You didn't need to subtract one, you know the end length is always odd so just shifting it down chops off the bit. I changed them to use --c instead of c--, it simplifies the bytecode and is faster in LSO.

*Since RShift copies the sign bit, we can force any negative number to be -1 with a bitwise-or. This makes the math fundamentally faster.

CODE

/*//-- Get Last Index of String Test in String Source --//*/
integer uGetStrIdxRev( string vStrSrc, string vStrTst ){
integer vIdxFnd =
llStringLength( vStrSrc ) - llStringLength( vStrTst ) -
llStringLength( llList2String( llParseStringKeepNulls(
vStrSrc, (list)vStrTst, [] ), -1) );
return (vIdxFnd | (vIdxFnd >> 31));
}


CODE

/*//-- Get Last Index of List Test in List Source --//*/
integer uGetLstIdxRev( list vLstSrc, list vLstTst ){
integer vIdxFnd = (vLstSrc != []) - (vLstTst != []) -
(llParseString2List( llList2String( llParseStringKeepNulls( llDumpList2String( vLstSrc,
";" ), (list)llDumpList2String( vLstTst, ";" ), [] ), -1), (list)";", [] ) != []);
return (vIdxFnd | (vIdxFnd >> 31));
}

NOTE: uGetLstIdxRev only works for string data types, and you may want to modify the separator to suit your needs (it should be something that WON'T be in any of the data)

*I might suggest using "|" instead of ";", or maybe an obscure unicode character.

CODE

/*//-- Reverse List Order (fast version) --//*/
list uListRevF( list vLstSrc ){
integer vIntCnt = (vLstSrc != []) - 1;
while (vIntCn--){
vLstSrc += llList2List( vLstSrc, vIntCnt, vIntCnt );
}
return llList2List( vLstSrc, (vLstSrc != []) >> 1, -1 );
}


CODE

/*//-- Reverse List Order (small version) --//*/
list uListRevS( list vLstSrc ){
integer vIntCnt = (vLstSrc != []) - 1;
while (vIntCnt--){
vLstSrc = llDeleteSubList( vLstSrc + llList2List( vLstSrc, vIntCnt, vIntCnt ), vIntCnt, vIntCnt );
}
return vLstSrc;
}


CODE

/*//-- Reverse String Order (fast version) --//*/
string uStringRevF( string vStrSrc ){
integer vIntCnt = llStringLength( vStrSrc ) - 1;
while(vIntCnt--){
vStrSrc += llGetSubString( vStrSrc, vIntCnt, vIntCnt );
}
return llGetSubString( vStrSrc, llStringLength( vStrSrc ) >> 1, -1);
}


CODE

/*//-- Reverse String Order (small version) --//*/
string uStringRevS( string vStrSrc ){
integer vIntCnt = llStringLength( vStrSrc ) - 1;
while(vIntCnt--){
vStrSrc = llDeleteSubString( vStrSrc + llGetSubString( vStrSrc, vIntCnt, vIntCnt ), vIntCnt, vIntCnt );
}
return vStrSrc;
}
_____________________
Truth is a river that is always splitting up into arms that reunite. Islanded between the arms, the inhabitants argue for a lifetime as to which is the main river.
- Cyril Connolly

Without the political will to find common ground, the continual friction of tactic and counter tactic, only creates suspicion and hatred and vengeance, and perpetuates the cycle of violence.
- James Nachtwey
Void Singer
Int vSelf = Sing(void);
Join date: 24 Sep 2005
Posts: 6,973
06-21-2009 00:42
sweet I like 'em, and I really should've used those OR'd returns...much obliged

ETA:
originally I was using (~(--c)) for the while loops but that just looked sloppy

they'll all get posted to the wiki shortly, and added to the library there, I have no intention of of Licensing them so I'll just add a "please cedit"... it's no big deal to me if people don't, but strife has my explicit permission to add one for his changes (which I'll be crediting anyway)

Further Edit:
well (--c) in the while test fails to catch the leading element, but if it's moved to the first parameter it works... I kinda wanted to avoid that because of the oddity that while order of execution is last to first in math operation, it's first to last in parameter execution

example:
x = "0123456789";
y = 5;
(llGetSubString( x, ++y, y ) == "6";)
(llGetSubString( x, y, ++y ) == "56";)

and I really hate depending on non-explicit order of execution in LSL, it's just asking for trouble. it works... now... but who could say in the future. (although it *should* be safe considering the layout for prim params, but that could be preserved with a find, whereas the internal math may begin to fail for other things...

not that LL would EVER commit such a heinous act... ::cough-choke-sputter-wipe_beverage_off_screen::

oh yeah, shaving off the last element DOES save about ~2ms in lsl... although ~- is the better way to do it...
_____________________
|
| . "Cat-Like Typing Detected"
| . This post may contain errors in logic, spelling, and
| . grammar known to the SL populace to cause confusion
|
| - Please Use PHP tags when posting scripts/code, Thanks.
| - Can't See PHP or URL Tags Correctly? Check Out This Link...
| -
Strife Onizuka
Moonchild
Join date: 3 Mar 2004
Posts: 5,887
06-21-2009 01:24
I just realized that --c was a mistake. I'm reverting.

It wouldn't copy the first element, I should have realized that immediately.

I needn't take credit, I get around enough, my name's in enough history logs. If people come looking, they will find me. They always find me :D
_____________________
Truth is a river that is always splitting up into arms that reunite. Islanded between the arms, the inhabitants argue for a lifetime as to which is the main river.
- Cyril Connolly

Without the political will to find common ground, the continual friction of tactic and counter tactic, only creates suspicion and hatred and vengeance, and perpetuates the cycle of violence.
- James Nachtwey
Void Singer
Int vSelf = Sing(void);
Join date: 24 Sep 2005
Posts: 6,973
06-21-2009 03:12
From: Strife Onizuka
I just realized that --c was a mistake. I'm reverting.

It wouldn't copy the first element, I should have realized that immediately.

I needn't take credit, I get around enough, my name's in enough history logs. If people come looking, they will find me. They always find me :D

lol isn't that the way it always is...

I have a few other functions I just libraried that'll take some of the same optimizations... I don't like how I handled uMatchListFwd, but I couldn't see and easier way, I do need to apply the increment decrement hack (-~/~-) to that one though

ETA: ok it WAS faster to skip the extra element... right until I found the infinite loop on zero element lists =X... throwing in the @-if/jump loop structure for the finals as I update them
_____________________
|
| . "Cat-Like Typing Detected"
| . This post may contain errors in logic, spelling, and
| . grammar known to the SL populace to cause confusion
|
| - Please Use PHP tags when posting scripts/code, Thanks.
| - Can't See PHP or URL Tags Correctly? Check Out This Link...
| -