|
From: Andre R. <and...@us...> - 2004-11-21 15:05:22
|
Update of /cvsroot/frontierkernel/Frontier/Common/source In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv2276/Common/source Modified Files: Tag: New_Tables_Experiment-branch langhash.c langops.c Log Message: Added hashmodify and hashtablemodify for assigning over an existing node in the table. If the caller already performed a lookup in the table and obtained the handle to the hash node, he can use these functions instead of hashassign and hashtableassign to eliminate another lookup in the table. Currently, we can only use this from langsetsymbolval, but since this is called a lot during UserTalk execution, is a worthy optimization. Index: langops.c =================================================================== RCS file: /cvsroot/frontierkernel/Frontier/Common/source/langops.c,v retrieving revision 1.3 retrieving revision 1.3.2.1 diff -C2 -d -r1.3 -r1.3.2.1 *** langops.c 31 Oct 2004 18:48:51 -0000 1.3 --- langops.c 21 Nov 2004 15:04:35 -0000 1.3.2.1 *************** *** 532,535 **** --- 532,538 ---- 5.0a18 dmb: require declarations! (if user's pref is set) + + 2004-11-21 aradke: if langfindsymbol located the node, use hashtablemodify + to prevent yet another lookup in the hash table */ *************** *** 539,546 **** if (false && langgetuserflag (idrequiredeclarationsscript, false)) { ! if (langfindsymbol (bs, &htable, &hnode) || (htable != nil)) { /*name is defined, or with statement set table*/ ! return (hashtableassign (htable, bs, val)); - } langparamerror (unknownidentifiererror, bs); --- 542,550 ---- if (false && langgetuserflag (idrequiredeclarationsscript, false)) { ! if (langfindsymbol (bs, &htable, &hnode)) /*name exists, htable and hnode are set*/ ! return (hashtablemodify (htable, bs, hnode, val)); ! ! if (htable != nil) /*assign to innermost local table*/ return (hashtableassign (htable, bs, val)); langparamerror (unknownidentifiererror, bs); *************** *** 550,559 **** else { ! if (langfindsymbol (bs, &htable, &hnode) || (htable != nil)) { /*name is defined, or with statement set table*/ ! return (hashtableassign (htable, bs, val)); - } ! return (hashassign (bs, val)); } } /*langsetsymbolval*/ --- 554,564 ---- else { ! if (langfindsymbol (bs, &htable, &hnode)) /*name exists, htable and hnode are set*/ ! return (hashtablemodify (htable, bs, hnode, val)); ! ! if (htable != nil) /*assign to innermost local table*/ return (hashtableassign (htable, bs, val)); ! return (hashassign (bs, val)); /*assign to currenthashtable*/ } } /*langsetsymbolval*/ Index: langhash.c =================================================================== RCS file: /cvsroot/frontierkernel/Frontier/Common/source/langhash.c,v retrieving revision 1.4.2.14 retrieving revision 1.4.2.15 diff -C2 -d -r1.4.2.14 -r1.4.2.15 *** langhash.c 20 Nov 2004 23:03:19 -0000 1.4.2.14 --- langhash.c 21 Nov 2004 15:04:35 -0000 1.4.2.15 *************** *** 2147,2150 **** --- 2147,2247 ---- + static boolean hashmodifynode (const bigstring bs, hdlhashnode hnode, tyvaluerecord val) { + + /* + 2004-11-21 aradke: code shared between the new hashmodify and hashassign (from where + it was stolen) + */ + + tyvaluerecord existingval; + boolean fllocal = (**currenthashtable).fllocaltable; + + existingval = (**hnode).val; + + if (fllanghashassignprotect) { /*protect externals from being smashed by assignment*/ + + if ((existingval.valuetype == externalvaluetype) && (val.valuetype != externalvaluetype)) { + bigstring bstype; + + langexternaltypestring ((hdlexternalhandle) existingval.data.externalvalue, bstype); + + lang2paramerror (badexternalassignmenterror, bstype, bs); + + return (false); + } + } + + /*carefully nuke existing value*/ { + + boolean flneeddatabase = (!fllocal && existingval.fldiskval); + hdldatabaserecord hdb; + + if (flneeddatabase) { + + hdb = tablegetdatabase (currenthashtable); + + if (hdb) + dbpushdatabase (hdb); + } + + disposevaluerecord (existingval, !fllocal); + + if (flneeddatabase && hdb) + dbpopdatabase (); + } + + (**hnode).val = val; + + langsymbolchanged (currenthashtable, bs, hnode, true); /*value changed*/ + + return (true); + } /*hashmodifynode*/ + + + boolean hashmodify (const bigstring bs, hdlhashnode hnode, tyvaluerecord val) { + + /* + 2004-11-21 aradke: call us instead of hashassign if you know the node with the + given name exists and you have its handle. this avoids another lookup in + the hash table. + */ + + if (val.fltmpdata) { /*val doesn't own it's data*/ + + if (val.fltmpstack) + val.fltmpdata = false; + else + if (!copyvaluedata (&val)) + return (false); + } + + val.fltmpstack = false; // 5.0.1: caller is responsible for actually removing it + + hashsetlocality (&val, (**currenthashtable).fllocaltable); + + return (hashmodifynode (bs, hnode, val)); + } /*hashmodify*/ + + + boolean hashtablemodify (hdlhashtable htable, const bigstring bs, hdlhashnode hnode, tyvaluerecord val) { + + /* + 2004-11-21 aradke: call us instead of hashtableassign if you know the node with the + given name exists and you have its handle. this avoids another lookup in + the hash table. + */ + + boolean fl; + + pushhashtable (htable); + + fl = hashmodify (bs, hnode, val); + + pophashtable (); + + return (fl); + } /*hashtablemodify*/ + + boolean hashassign (const bigstring bs, tyvaluerecord val) { *************** *** 2168,2175 **** 5.0.2b13 dmb: set fltmpdata false & call hashsetlocality before hashinsert case */ hdlhashnode hnode, hprev; - tyvaluerecord existingval; boolean fllocal = (**currenthashtable).fllocaltable; --- 2265,2274 ---- 5.0.2b13 dmb: set fltmpdata false & call hashsetlocality before hashinsert case + + 2004-11-21 aradke: move code for assigning over an existing value + to hashmodifynode, shared with hashmodify. */ hdlhashnode hnode, hprev; boolean fllocal = (**currenthashtable).fllocaltable; *************** *** 2199,2241 **** } ! existingval = (**hnode).val; ! ! if (fllanghashassignprotect) { /*protect externals from being smashed by assignment*/ ! ! if ((existingval.valuetype == externalvaluetype) && (val.valuetype != externalvaluetype)) { ! bigstring bstype; ! ! langexternaltypestring ((hdlexternalhandle) existingval.data.externalvalue, bstype); ! ! lang2paramerror (badexternalassignmenterror, bstype, bs); ! ! return (false); ! } ! } ! ! /*carefully nuke existing value*/ { ! ! boolean flneeddatabase = (!fllocal && existingval.fldiskval); ! hdldatabaserecord hdb; ! ! if (flneeddatabase) { ! ! hdb = tablegetdatabase (currenthashtable); ! ! if (hdb) ! dbpushdatabase (hdb); ! } ! ! disposevaluerecord (existingval, !fllocal); ! ! if (flneeddatabase && hdb) ! dbpopdatabase (); ! } ! ! (**hnode).val = val; ! ! langsymbolchanged (currenthashtable, bs, hnode, true); /*value changed*/ ! ! return (true); } /*hashassign*/ --- 2298,2302 ---- } ! return (hashmodifynode (bs, hnode, val)); } /*hashassign*/ |