class hashTable{ ; User methods hasKey(byref k){ return this[6].call(k, "Cdecl ptr") ? true : false } hasVal(byref v){ return this[9].call(v, "cdecl ptr") ? true : false } valGetKey(byref v){ return this[9].call(v, "cdecl str") } delete(byref k){ return this[4].call(k, "Cdecl") } clone(){ ; Use: clonedHt := ht.clone() local clone := this[14].call() return new hashTable(this.length(),, clone) } forEach(udfn,uParams:=0){ ; accepts function name, func / bound func obj. ; binary code address, eg registercallback("f", "cdecl fast") <- cdecl needed on 32bit ahk. Fast option recommended if ok. local cbid,r,cbfn this.setUpcalloutFunctions(udfn, cbfn, cbid) r:=this[8].call(cbfn, "uint", cbid, "Ptr", uParams, "cdecl") this.calloutFunctions.Delete(cbid) return r } forEachVal(byref val,udfn,uParams:=0){ local cbid,r,cbfn this.setUpcalloutFunctions(udfn, cbfn, cbid) r:=this[13].call(val, "ptr", cbfn, "uint", cbid, "Ptr", uParams, "cdecl") this.calloutFunctions.Delete(cbid) return r } count(){ local table := NumGet(this.table+0,0,"Ptr") return numget(table+0, A_PtrSize*2+12,"uint") } length(){ local table := NumGet(this.table+0,0,"Ptr") return numget(table+0, A_PtrSize*2+08,"uint") } getMaxload(){ return this.maxLoad } setMaxload(newMax){ local prevLoad local table := NumGet(this.table+0,0,"Ptr") prevLoad := this.getMaxload() numput(newMax, table+0, A_PtrSize*2,"double") this.maxLoad:=newMax return prevLoad } splitAdd(keys,vals, del:="`n",constVal:=false,isByref:=false){ if (del == "") return this.splitAddNoDel(keys,vals,constVal,isByref) if isByref ; For very large input, pass keys and vals by address and specify true. Improves performance. return this[constVal ? 11 : 10].call("ptr", keys, "ptr", vals, "wstr",del, "cdecl") return this[constVal ? 11 : 10].call("wstr", keys, "wstr", vals, "wstr",del, "cdecl") } splitAddNoDel(byref keys, byref vals, constVal, isByref){ ; Call splitAdd, specifing del:="", instead of calling this directly if isByref ; For very large input, pass keys and vals by address and specify true. Improves performance. return this[12].call("ptr", keys, "ptr", vals, "int", (constVal?1:0), "cdecl") return this[12].call("wstr", keys, "wstr", vals, "int", (constVal?1:0), "cdecl") } addFromFile(path){ ; See toFile for file layout. local keyBytes, valBytes, error, success local keyBuf, valBuf, nKeys local fo := fileOpen(path,"r") if !fo throw exception("failed to open file: " path) try keyBytes := fo.readuint() ; Read length of keyBuf, in bytes catch error throw error try nKeys := fo.readuint() ; get number of key/value pairs catch error throw error success := keyBytes == fo.rawRead(keyBuf,keyBytes) ; read the keys try valBytes := fo.readuint() ; Read length of valBuf, in bytes catch error throw error success *= valBytes == fo.rawRead(valBuf,valBytes) ; read the values fo.close() if !success throw exception(A_ThisFunc " failed for path: " path ".") this.checkIfNeedRehash(nKeys) if !this[15].call(&keyBuf, "ptr", &valBuf, "uint", nKeys, "Cdecl") ; add to table, addNullDel.c return 0 return keyBytes+valBytes ; return number of bytes in the added data. (only includes key/val bytes) } copyFrom(ht){ ; Adds all key value pairs in hashTable ht, to "this" /* typedef struct copyParams { tableData** destTable; pfnLib lib; put pput; } *pparams; */ ; Set up copyParams, these are uParams for ht.forEach(...) local uParams varSetCapacity(uParams, 3*A_PtrSize) numPut(this.table, uParams, 0, "Ptr") ; hash.h numPut(hashTable.fnLib, uParams, A_PtrSize, "Ptr") ; hash.h numPut(hashTable[5], uParams, A_PtrSize*2, "Ptr") ; hashPut.c this.checkIfNeedRehash(ht.count()) ht.forEach(this[16], &uParams) ; this[16] is copyFromHashTable.c, see initBin() and initBoundFuncs() (in the last it is just a comment) return } toFile(path){ ; File layout: ; bytes 0 - 3, uint: keyBytes, number of bytes for keys ; bytes 4 - 7, uint: count, number of keys (and values) ; bytes 8 - 8+keyBytes-1, keyBuf, all keys, '\0' delimited ; bytes 8+keyBytes - 8+keyBytes+3, uint: valBytes, number of bytes for values ; 8+keyBytes+4 - 8+keyBytes+4+valBytes-1, valBuf, all values, '\0' delimited ; local raw, success local fo := fileOpen(path,"w") if !fo throw exception("failed to create file: " path) raw := this._toString("","",1,true) ; get keys fo.writeuint(raw.bytes) ; write length of keys fo.writeuint(this.count()) ; write count success := raw.bytes == fo.rawWrite(raw.buf, raw.bytes) ; write keys this.free(raw.buf) raw := this._toString("","",2,true) ; get vals fo.writeuint(raw.bytes) ; write length of vals success *= raw.bytes == fo.rawWrite(raw.buf, raw.bytes) ; write vals this.free(raw.buf) fo.close() if !success throw exception("Failed to save table to file. ( " path " )") return raw.bytes } rehash(newLength:=0){ ; "Manual" rehash. Typical usage, when removed many values, shrink the table. local newTable local prevLength:=this.length() local table := NumGet(this.table+0,0,"Ptr") if (newLength==0) newLength:= (this.count() / this.maxLoad) * 2 ; If new length is 0, choose the new length to be half way from reaching the maxLoad. if (newLength == prevLength) ; No need to rehash if already at desired length return prevLength this.initSize(newLength) numput(this.nextSize-1, table+0, A_PtrSize*2+16,"uint") newTable:=this[3].call() ; rehash. NumPut(newTable, this.table+0, 0, "Ptr") this.size:=this.length() ; not really needed. return this.size } ; Persistent related deletePersistentFile(){ ; Deletes the file in this.path ; Note: you should also call makeNotPersistent() if you do not want the table to be saved when exiting the script ; Returns true on successful deletion. return fileExist(this.path) ? (!this.fileDelete(this.path)) : false } fileDelete(path){ ; help function for deletePersistentFile(). fileDelete, % path return errorlevel } makePersistent(path:=0){ ; Specify a path / file name where the table will be saved upon release. this.path := this.path && !path ? this.path : path ; Update path if specified this._isPersistent:=true } makeNotPersistent(){ ; Unflag the table as persistent. return this._isPersistent:=false ; keep path } getPath(){ ; Returns the path of a persistent table return this.path } _isPersistent:=false isPersistent(){ ; returns true if persistent, else false return this._isPersistent } _loadedFromFile:=false loadedFromFile(){ ; returns true if the table was loaded from file, else false. return this._loadedFromFile } ; Methods for viewing the table. toString(del1:="`t=`t",del2:="`n"){ return this._toString(del1,del2,0) } keysToString(del:="`n"){ return this._toString(del,0,1) } valsToString(del:="`n"){ return this._toString(0,del,2) } ; toTree not available in v1 version. /* toTree(opt:=""){ local gui,tv,parents,cbfn if (opt == "") opt:="R20 w400" gui:=guiCreate(,"Hash table - tree view") tv:=gui.addTreeView(opt) gui.addText(,"Number of key/value pairs: " this.count() ". Table length: " this.length() ".") parents:=[] cbfn:=ObjBindMethod(this,"buildTree",tv,parents) this.forEach(cbfn) gui.show() WinWaitClose("ahk_id " gui.hwnd) gui.destroy() return } */ ; Print tableData struct. printTableData(show:=true, extra:=""){ local table := NumGet(this.table+0,0,"Ptr") local outstr outstr:= "Buckets: " . numget(table+0, A_PtrSize*0+00,"ptr ") . "`n" ; Buckets (the address) . "tableSizes: " . numget(table+0, A_PtrSize*1+00,"ptr ") . "`n" ; tableSizes (the address) . "maxLoad: " . numget(table+0, A_PtrSize*2+00,"double") . "`n" ; maxLoad . "length: " . numget(table+0, A_PtrSize*2+08,"uint") . "`n" ; length . "numKeys: " . numget(table+0, A_PtrSize*2+12,"uint") . "`n" ; numKeys . "nextLenInd: " . numget(table+0, A_PtrSize*2+16,"uint") ; nextLenInd . "`n`n" . extra if show msgbox, 0x40, % "Hash table data", % outstr return outstr } ; ; End user methods ; ; Nested class ; when making a new hashTable, a reference to a "router" is returned. the "router" contains the reference to the new hashTable object. See __new() class router { ; For familiar array syntax, i.e., [value := ] myHashTable[key] [ := value] __new(ht){ ObjRawSet(this,hashTable,ht) } __set(byref k, byref v){ this[hashTable,5].call(k, "wstr", v, "Cdecl") return v } __get(byref k){ return this[hashTable,6].call(k, "Cdecl str") } __call(f, p*){ return this[hashTable][f](p*) } __delete(){ static ht:=hashTable ; Because needs to call destroy() for persistent tables even if hashTable has been deleted. this[ht].destroy() } } ; Init methods. Most init methods are called by __new. NOTE: There is "static" init in maketableSizesArray() static init:= false maxLoad:=0.7 __new(size:=23, path:=0, clone:=0){ ; The clone parameter is intended only for internal use. When cloning a hash table. if !hashTable.init hashTable.initBin(),hashTable.makeFnLib() this.icbfn:=registercallback(this.traversecalloutRouter,"cdecl Fast",6,&this) this.initSize(size) this.initTable(clone) this.initBoundFuncs() this.loadFromFileIfPersistent(path) return new hashTable.router(this) ; returns a "router" object, which has a reference to the new hashTable. Use all methods on the returned router object. } loadFromFileIfPersistent(path){ if (path && fileExist(path)) this.addFromFile(path), this._loadedFromFile:=true ; The file exists, load if path this.path:=path, this._isPersistent:=true ; If path is specified, set _isPersistent to true, for auto saving on delete. return } initBin(){ ; Can be freed via freeAllBins() (you shouldn't) ; See c source local pnewTable,pdestroy,prehash,remove,pput,pget,pfindKey,ptraverse,pfindVal,pmultPut,pmultPutConst local pmultPutNoDel,pforEachVal,pclone,paddNullDel,pcopyFromHT,pgetFromHash,pnext,j,raw if (A_PtrSize == 4) { pnewTable := [2203276887,267526380,1009009680,807695499,874806411,539231431,4060086272,608440591,2245525272,2304275648,3036974531,0,4280550537,2311095767,2235855875,823424246,2332224466,2416232195,0,956416643,2347791830,4063765572,608964623,276007192,1328071,4060086272,139137295,2332312457,2302944324,3632863299,1528874115,834887518,2432035776,2425393296,2425393296,2425393296] pdestroy := [1398167381,2334977155,2336236612,2336498780,608471312,273320732,1165281669,2422669105,747307659,1961723320,649366833,0,2332317067,344522869,72613668,2299024779,1409229844,606898436,1409283465,1979090180,608472031,2333117212,3347255370,1926183169,2298645439,1409229828,608471812,2298514204,2336236612,3296920643,1600019244,2430664541] prehash := [1398167381,2336025731,2337285188,71994128,2333622923,4286939452,673479817,18383887,3229810688,608471297,608471828,269480532,1284048962,267520036,203703313,1149829259,1149961252,76097572,608471844,273743700,3347693701,14713871,1149960192,9130020,2299809931,1351291991,265454864,39812,608487168,44,611617536,7769388,881526923,1962313137,649366898,0,2332317323,444206,251658240,2238057143,2407796681,2197815296,3224437442,443,3417247488,16958083,3252259272,3643344353,3071265673,2238119498,837187017,611645394,2500103464,0,143329027,74828165,3247001835,3229942155,831125621,4002016645,1150000757,9130020,2198884491,19670084,740586635,2182075961,4294967156,76087435,608471844,72417108,1344554123,76087435,608471844,72417108,2302461059,1600019448,814334813,3224483563,3296960235,1539322172,3277676382,2425393296,2425393296,2425393296] remove := [1398167381,2334977155,256386140,2238067639,3817082870,251658240,29349559,822083584,264843712,3246643119,153914625,4203335681,688251585,265783802,1716196535,3816149637,405040265,1076133003,1066127921,2333112311,2416217351,1149843595,4286913572,11109391,3979411456,1468778885,1714058244,812986937,1820966961,317396004,649366928,0,1127003919,1110194534,3229816437,1976056065,611093487,608471828,1015244312,427032578,4253616011,74760325,3102459785,3089941635,2,1566531163,2347599299,2304144391,1149960261,344540196,72417060,2299021195,1149969412,1358906404,608471812,607947076,2332315903,2336236612,342393600,751076097,440,1600019200,1153942365,6180,3224436736,971622705,2214592511,3224448196,1566531163,611617731,2332461340,2733311063] pput := [1398167381,2338122883,2340168788,2339644540,1719149684,251673219,82308,3955241216,2379778306,2204500312,1962957372,4492788,609519876,604277032,1418401791,3314100260,3071262769,2305180172,2197833036,3275293120,1150021747,1418555428,9128996,270816393,1210340493,203707529,2299547787,2298750068,2332566612,604276992,2198362111,21767292,874792073,12157967,80150528,3108,1712848640,2298494595,3414429633,822083584,2298670016,22580696,1581024102,2381608192,2298740804,2301109324,402596868,2422657585,1443673871,1342998886,956416643,2347857626,2301109324,1149961281,29838372,0,2231921033,2336978112,2301895748,608471816,608487280,44,2346397952,342919936,2366654603,1418264918,1351165988,611114772,608995624,610044200,611114796,138992680,3923757529,1316477149,3296968753,1600019292,1150010205,1418424356,9127972,210305163,2309680016,138447814,4280550537,1854473303,1556382472,440,1600019200,45663069,822083584,4274514395,45678591,822083584,4282247643,1150025727,2089381924,76088356,207093540,1881439371,4290250633,3959422975,2425393305,2425393296,2425393296,2425393296] pget := [2336025731,2369791044,2334925908,609519872,609520912,609519912,273713932,136598665,1210340491,69489801,76087435,608471844,139525956,2089013809,1963011108,139496195,3296972937,2425406268,2425393296,2425393296] pfindKey := [1398167381,2332355715,253502556,2238067639,3447984118,251658240,29218487,822083584,264843712,3246642607,154963201,3934900225,688251585,265652714,1716196535,3816149637,1962398257,76357668,149,611093248,5605668,673469579,711,1418395648,747313188,267224322,33924,7769344,1435224453,1713665028,645214777,2305212465,3942786164,884412170,876176963,2200008002,3359179200,3071274869,1711416436,3816579,1166749300,1958774016,3955591443,7769539,251676043,35943607,3983917189,673465483,131271,3901292544,1527039107,3277676382,673465483,65735,3296919552,1541966084,3277676382,3224502065,3375485489,4294925545,3955241471,2425393363,2425393296,2425393296] ptraverse := [1398167381,3677484593,2336025731,2337285188,273189632,2215627141,265,11867277,2298478592,2334925908,2990312208,2215640965,230,1150020913,3280166948,611617025,610044176,608471304,608471828,608471388,138906380,69485705,2298759051,1426007044,4169357348,2122151167,1958774041,33063791,126582389,3230006665,9667599,3347644416,4169381099,113150,1685389312,1284048779,1149839396,1200301092,604276996,1411662987,2332315903,76089415,608471844,72417108,1411662987,4280564873,3984917584,606356619,673467531,1166621300,609520384,2199030608,2231440490,3097457865,4294967294,1530709123,3277676382,2766915889,649366928,0,3347708041,4294917609,649367039,0,1344558219,740588683,311104139,3946448009,608471992,2332068688,3330478152,265173249,4294899586,112895,2968190976,2425393296] pfindVal := [1398167381,2333142147,254551132,2238069687,2844004351,822083584,29459401,1262256998,153914624,1150022517,9118756,2232438923,609520082,2338944008,608487168,4,608471296,608471820,609520396,2419362564,1031075461,1452001669,1713992712,729102905,881442865,2299783972,666668534,0,1127528207,1110718822,3229824629,1976056065,607423471,708608870,2334815232,1979090230,608469955,1149960452,1144587300,2775910436,823182467,1600019392,3062743901,0,3945018507,71732182,1527825539,3277676382,3375492401,4294925801,2425393407,2425393296] ; -O3: pmultPut := [4281423701,3968029526,615811964,160,3347645163,1711359885,4266032259,267613440,2626367159,38948,268403968,1059341461,807683271,0,673465543,0,874792135,0,649366928,0,874792075,673465347,256052365,2238054839,1712354496,2215635001,1243,673465475,1725819649,125169029,1059355776,2235004160,608487423,64,824931584,7769563,807683211,2619640971,16777216,1091341784,1711388431,678740101,266877286,278404,29590272,3224492779,673465345,1076118727,1,1989002731,666668288,0,1978500454,612139019,2232352831,1221,2232418181,1213,673475723,36521101,1210336393,2334393481,9708676,285147136,1149889925,2215589924,647,874792075,268457101,2314224269,55321668,9970820,3314089984,941900939,1143237769,957368461,3247640525,2357972361,38948,969998592,266897864,3356017043,81560591,1284177920,4186122276,3481669390,2332033028,2202281028,3906015200,3766737143,264780039,3375481159,2215624837,179,2552540299,2332033024,2201232460,3071214072,2332052812,1714955372,251678089,324228,613190400,152,251852931,4061220023,38635878,80708623,2357919744,38948,66618112,290240271,1300850420,2894335748,2332033028,9970828,4169334784,1287065348,2305226257,2215577165,1161,2552532107,2197815296,3071215096,1727533388,252202377,288388,613190400,152,252180611,4195437751,172853606,71533839,2357919744,38948,1421283072,129629201,1711276032,2332841353,690496596,2378170818,1418328170,3988870180,22383875,1143231625,2298733249,2337285204,2369266772,1141047852,3526446116,2552529923,1711276032,2197843727,3313697218,281051920,4031058191,1143231545,1150019959,3238088740,1411662907,2215627401,267,874792075,1143231625,1143229579,1149878785,2223721508,38948,23694592,673475641,1343534863,941900939,1209305446,2249190025,215,1277455499,1277449353,3506563465,2552534155,251658240,2336885943,1716266068,2337279113,2370053196,1413022289,1418274852,2249149476,163,3506563465,2552534155,251658240,2336885943,1716266068,2337279113,2370053196,1413022545,1418274852,2071350308,3506563465,2552534155,251658240,2336885943,1716266068,2337279113,2370053196,1413022801,1467361316,2894850441,38948,265355520,5065911,1342998886,1143229579,956649869,1982342228,608996150,265355572,5065911,1342998886,1143227531,956743811,1982342212,608996122,18124084,2552532107] pmultPut.push([251658240,2337346743,1714955340,2336298121,2335712324,826811468,458526189,1820943874,2223767048,37924,605325568,1143231625,1284182271,3314102308,2619638923,2365587456,3224455180,649366928,0,1091876623,1163168102,29393664,4034118457,874792075,1143231627,4160866609,673465347,357337446,608471550,608471860,33030448,610045400,608471404,612666160,144,1552482443,1552748580,1552508964,1552616484,1351301156,610044176,609519876,2298514184,2223711236,37924,139525888,1814330499,264472833,96132,612666112,148,203687111,4278190080,609520400,608996204,51000,2298478592,3531933800,251938953,50309,614238976,144,1747209355,311104395,2307523721,3339750360,2892868,822083584,339905499,2198882955,1149829568,1116284964,611114772,608995624,610044200,611114796,139123752,3923757529,2265962717,313,1076118667,2232402053,288,3341727503,2630724,2332033024,9970844,1776877568,2315255803,666668534,0,2215640965,4294966256,3062743089,0,251773059,1715541175,256250937,99461,264714496,97414,3531957760,3342459509,4223829007,1418461183,3531948068,8225807,3271622656,4294684649,2332264959,9446532,1122566144,2248146943,1753485311,822083585,29393856,1091876623,1175730534,3342409333,2238061174,971666898,608487367,64,1099239168,3925868539,4294966031,1153943353,16420,2215575552,4294966015,265454950,4294648708,608436735,614239016,152,4294618089,609520639,2243965248,2206430674,3224468676,1566531163,649366979,0,2299019403,2223711236,37924,72417024,941900939,2334393481,9708676,1358888960,608471812,141265216,2215624837,4294967008,3095184515,1,1566531163,612666307,148,69485705,2418312331,2298478592,2223711236,37924,206634752,2418318475,2298478592,4271565059,1284243455,1821059108,3526440996,1143227531,1277451401,2520205,1344059151,1432127846,29524736,4034253113,1277451403,4294785769,440831,3370713088,3120562171,5,4294688489,309759,3035168768,3120562171,3,4294683369,178687,2699624448,3120562171,1,4294678249,264714751,4294593412,3531958015,4269835279,3230007295,441,3242462976,3655975681,3355443193,4203588,3909091328,4294965703,2425393296,2425393296,2425393296]*) pmultPutConst := [4281423701,3967898454,172,3357842571,2332033024,13640884,116064256,2520205,1200473993,2088986113,1962999366,2311074291,824976508,2345109961,13378732,82509824,3515467657,2365736845,2204500305,16647548,76410485,612141330,612141908,2311751980,13640884,1284046848,1149845540,3071237156,2245953798,608487423,56,614238464,200,608474383,1149855315,2223714340,52260,266371840,3640125649,956817539,3242659784,1149879689,3364450340,2223630377,32804,4164979968,2198071489,1149829568,3770774564,608471299,4282551676,1149888553,1150118948,3979411501,2015642761,3424945155,2298478592,8660100,2223702016,52260,281051904,1612989577,649366928,0,941900939,210626561,28774214,1958774118,1144743440,2215587876,1397,3942761859,2088986335,1962946596,612139019,2232352851,1824,740574347,2232402053,1812,1009009863,0,36521101,1143227529,2334393481,12854404,285147136,1149889925,2215587876,510,941913227,1334691721,911510800,4030893328,1277445257,3357836291,956301312,613190600,200,608473871,1555435336,3506522148,2467286841,264964289,425860,251495168,108430863,3766681600,608487183,72,4159230208,132154328,1192224825,264275397,36996,614238976,200,251787395,1718815927,2215579529,1790,3357838475,2197815296,3071214328,1727140172,251809673,448644,615811840,200,251918467,4095102135,72321382,112362511,3071213568,2213942860,2305164536,2215577167,1683,374126351,100172792,139430246,108299279,3071213568,2214205004,2305165304,2232355407,1621,374650639,608487420,1864,1468622336,2347469068,2337023060,690758780,2378170819,1552545867,3254872100,807683075,3357840387,3238002688,1502413801,2378772737,56628,1552482304,2626377764,51236,611617024,615811940,208,40832870,2197930371,3229814978,1074859792,608975856,2313777752,13640884,1149960192,1955285028,2089378852,2626235428,51236,1005584640,258483316,34180,2346682624,2335712348,2368742516,3071214356,2305185556,1351435796,1993685249,319589737,1326233359,1443662182,956453005,2371319509,3071218444,2305183500,1351439884,1993685251,319589701,1326233359,1443662182,956584077,2368960213,3071218444,2305183500,1351439884,1993685253,319589665,956743811,213323717,210331215,2333046358,2369266780,3071214356,2305185556,1149978132,1955278884,4281418788,813468006,608472062,604277084,3290727563,4278190080,2344716560,2235573316] pmultPutConst.push([3749973952,989855745,2371888204,2467237953,612645314,204,146838287,813961154,2197815300,239084668,69568015,1552613376,3682955300,63013903,2223702016,52260,33260288,1711322895,2215575945,1191,3424945291,2197815296,3071214331,2305163840,2215576129,1157,3424945291,2197815296,3071214587,2305164352,2215576641,1123,3424945291,2197815296,3071214843,2305164864,2215577153,1089,3424945291,2197815296,3071215099,2305165376,2215577665,1115,3424945291,2197815296,3071215611,2305165888,2232355393,1081,3424945291,251658240,1712079031,3087810953,7,1814330499,2339468806,829957236,611092955,608471364,613714760,132,2089539721,2626366500,51236,2311979264,615812085,208,175050598,2197930115,3263369413,1292963600,608451056,2347333492,2303206468,13116572,1552613376,1821080612,2089370660,3028888612,53284,1004011776,8397980,2215575552,146,3424957579,251658240,1715868855,2202080393,1144586688,2054570020,1175762703,1076130955,1091864934,956387469,2338813654,13378716,3071213568,2305184540,1351438620,1993750786,614239057,204,1394390799,1360824678,956518541,2335930070,13378716,3071213568,2305184540,1351438620,1993750788,614239013,204,956678275,481759174,478766675,2333046353,13378716,3071213568,2305180436,1149976852,3677443108,2619651213,2298478592,1715741772,2332105865,2369266756,9970844,1141047296,3892390948,941900937,3223618699,2332033024,611617024,610044176,611617548,273713968,69497993,136598665,76087435,612666148,196,2198360319,10233020,2298544128,608996293,1619267396,2332033025,12854404,1284046848,80167972,3108,2333146880,2336498764,3341821044,0,138971392,2619640971,2298478592,3380937840,18515215,3029008384,49188,613190400,152,311105163,2307523721,3339750384,3417156,822083584,339905526,2198887051,1149829568,1116287012,611114772,610044208,611617072,611114804,139123760,3923757529,2265962717,330,1009013899,2232406661,259,3492054155,822083584,615812077,200,1711322895,807683209,4294602729,608472063,264275244,4294615940,2347993599,2334925948,13640884,3224436736,2520205,251773059,1715541175,1967526969,1992767811,3531957823,3342461557,740588681,3357842569,2298478592,13640884,1153892352,15396,2215575552,4294965856,1153942785,80932,1374224384,2315255802,666668534,0,2089404217,2626235428,51236,615811328,208,4196828175,2238119935]*) pmultPutConst.push([29979858,3923675589,4294965720,649366928,0,2332050825,12592260,4008247296,2348810238,1284048960,76104740,612666148,196,2332315903,2301633604,2223711236,50212,72417024,1009013899,1143229579,1300877957,4253290248,2181038078,44228,112640,1583022080,834887007,612139968,2265908844,4294966491,3424945291,2332033024,13378740,3071213568,25781760,440,4249282816,2223767551,50212,608471296,612666116,192,2334393481,12854404,1358888960,615811852,192,2313750153,2315255806,2336498796,824976508,609520576,615287616,204,3492066443,2415919104,2520205,1163704079,478766592,29393729,4034249273,1143237771,740588681,3492066441,3909091328,4294966606,740588683,807685259,3029062193,53284,481758976,478766672,29524817,4051031353,740588681,3492066441,3909091328,4294966034,1153941553,80932,3305177088,4294501353,309503,4192796672,3103784955,3,4294701033,178431,3857252352,3103784955,1,4294695913,440575,3521708032,3103784955,5,4294690793,608487423,1608,4189055232,1153957887,346148,2733178880,3355443193,71836740,3909091328,4294965653,1210336455,3,4294543593,608487423,584,4185647360,1153957887,84004,1860763648,2432696313]*) pmultPutNoDel := [1398167381,2340220035,10495148,3029008384,39972,608487168,1076,1961723136,2210410775,2204500416,16664188,1149891957,3221303332,874792073,2089545865,3766693924,4159230223,132154328,1192228921,2314023367,608471489,704153916,608471496,4164980040,2198071489,1149829568,3770762276,608471299,2214103372,3358130664,1076118665,2299069581,22291524,608471536,273059152,941900937,2552530059,1711276032,6831235,22774799,3163226112,40996,268403968,89989,1015244288,2215575662,996,2485421195,3338665984,271364,285147136,1150011273,76100644,612666148,148,3280539903,2552530059,822083584,79106002,126445160,2305212465,3071214151,2305191428,2305163859,612666115,144,1814318221,1747211405,2332149123,608995584,609519888,273713932,69500041,136598665,76087435,612666148,148,2198360319,23864444,2215625353,652,673465481,2485421195,3338665984,795652,285147136,2332579977,3345753180,0,75008256,673469579,2232408965,588,2418326667,2332033024,2338858060,2299693847,4169763332,1153896587,11300,3677421568,2333360779,3229814858,608471297,339904808,673475807,673467529,740580489,673475807,3641199324,3723091913,3448115160,2348810238,9708676,1149829120,2223703076,36900,604276992,2485421195,4278190080,3163229264,36900,2332526848,9970820,2204499968,251684924,4294878597,2093253631,440,1600019200,3062743901,0,2485421195,3338665984,271364,285147136,1150011273,76100644,612666148,148,3280539903,2552530059,822083584,610024393,79105848,1334404712,3264417538,2366081382,3325628483,146838287,3246657474,2197815297,238036092,28739087,1284177920,3380952100,25854991,3071213568,33129222,251890022,134020,1186402048,49906434,37980518,32146447,3071213568,4186113094,1133078019,3380875012,251658241,2198226615,2305164537,2215577155,424,138852111,1711667587,252199817,100228,1186402048,133792522,172198246,23758095,3071213568,2305166406,129502275,2197815296,104866940,1284194934,1149850660,3224447012,2332759181,1716528204,2197909263,3246588352,281182992,4030861583,1143227451,1284237682,1149979684,3355519012,1210338361,4258759695,3062759423,0,1175762703,1125419366,956416131,254813252,4294818950,347541503,344548934,22056259,807687225,4255614479,3071279103,2305185292,1351439116,609499394,2458259248,268435453,1716915383,2371030153,1413022544,2249142308] pmultPutNoDel.push([4294966653,1443673871,1393330534,956584077,254813268,4294797446,213323775,96502614,807683129,1393330534,4250109455,3071279103,2305181204,1189692180,2432696317,2520205,2223702665,36900,4256884992,2422669311,2299019403,2301109332,2223711236,37924,72417024,2485421195,2298478592,1358898236,609520388,140151080,4294743017,7769599,2089009201,252067876,4294893959,112660479,3087239526,1,4294912233,7769599,807685259,1989001265,666668288,0,1175762703,1125419366,956416131,3924915649,4294966461,1720,4271499520,2422669311,1464,4270713088,3062759423,0,1208,4269664512,3062759423,0,952,4268615936,3062759423,0,696,4267567360,3062759423,0,440,4266518784,3062759423,0,830260355,1600019392,2425406301,2425393296]*) ; -Ofast: pforEachVal := [1398167381,2337074307,1718101100,32131,26772495,3677421568,1711391619,6126723,456428800,1150022261,4281425956,740574407,0,9171593,2232436875,2373481673,48436,1955135488,814429220,2243835019,3344790774,3155012,2415919104,2520205,1317788549,255030280,1711293879,829751609,1418313777,401287204,649366928,0,1163179791,339305984,2441416513,2197815296,3627614656,1418455669,2204510244,1946161468,2234944291,2344187382,2338333764,273189632,956417923,3095950031,1,1531757699,3277676382,673469577,1948537995,740574339,612141313,608471824,608995628,609519876,609520404,608471408,609519880,71731980,4280550537,2204902484,1418461176,2215585828,143,3229950846,4169380468,1300565761,2315255807,2335188084,2424892214,2520205,673469579,4294932713,4277699583,673465543,1,4280714511,109838335,1009013897,941900937,2298758795,1149969412,1358914596,138840836,2334393481,4284752964,1149961296,881419300,72417060,807695499,941900939,1009013899,628422277,1955268233,1284202532,915089444,18116227,729139589,283756169,3355443199,2630724,3942645760,611617693,608996192,2335607604,235178294,4130458859,1877596977,2214592510,4273491140,1543503871,3277676382,2425393296,2425393296,2425393296] pclone := [1398167381,2338122883,2339382340,2339644540,407931648,337925257,1074794482,286257672,2332828740,1418265680,394987556,69489801,2299543691,1476338692,2311095568,608471495,4119072572,2332033028,2339382340,340822784,2333366153,3531935824,81036303,1153892352,19492,2089484288,143346724,12399757,2298478592,2335450228,3984963884,63144975,1820917760,1988961316,666668288,0,1948533899,203687111,822083584,2299592667,2334663748,2334401604,3062694976,0,1711391619,4267211907,2348119296,824452164,138447862,1711392387,4268784771,2381673728,76094212,608471844,2299592564,906268103,2334393481,4285801540,2344978704,2334401604,1116537936,2378643728,2467237959,264387009,3238576275,56132623,4219666432,1334185742,2298478595,608487376,48,266371840,3640125649,956817539,3276214232,1953808517,2198517519,2305163768,2424573711,251658243,2197965495,2305164024,2215576143,882,72005391,1711536259,251940745,218244,1253510912,83395334,105875814,53904399,3071213568,4169336906,1334404613,1719930632,251658243,2198489783,2305165304,2232355407,840,206223119,807683271,7,206539110,1153948041,11300,1418264576,3240708132,1284096001,3917692964,65650952,2298593667,3241681996,1284047841,210584612,1727529218,2198433551,1149440192,2197892132,1418399937,286207012,1413214280,3815913508,1143229579,807683211,1210340491,1278855169,2054438948,1108129551,740574345,1192003942,956385421,258438859,1716126903,2337211529,2368480324,3409510984,3071235190,2305182212,1149980420,1217211428,1993029891,79105857,76113482,608471887,71863596,779537209,1241822991,1325697382,740574347,956647565,253458123,1716126903,2337211529,2200708164,3275294400,3071215734,2305180180,1149978388,1351296036,272993544,1116586553,3247640336,2467284281,264308928,123780,251560704,31098383,3498639360,3507478659,2212034536,4030269408,835077903,1958774235,179769202,1711405187,251678089,154500,1253510912,49840898,38635878,37782543,3071213568,4169335882,1300850179,629411588,251658242,2198227639,2305164536,2215577165,522,139114255,1711667331,252202377,126852,1253510912,133726986,172853606,30704911,3071213568,129698890,1711276032,2299284873,608487409,44,609519872,29436228,608995776,149521216,2198071745,1284047297,3787534372,608995587,34377016,258402305,3229815151,608469776,3246588204,609520400,1343295276] pclone.push([609499632,2346940208,2335712332,2302944340,1004011976,1950360652,213323625,1284073026,1217200197,1993226497,481759065,1552508490,1217200205,1993226498,481759049,1552508490,1217200205,1993226499,481759033,1552508490,1217200205,1993226500,481759017,1552508490,1217200205,1993226501,481759001,113279818,2305214009,1979731292,347541257,1418290754,1149960261,13051940,0,2298771593,1149962344,2089493540,9124900,606356617,874792075,277546755,74830469,3263790827,3229942411,1150023797,42543140,606356619,2232402053,4294966356,1881425035,1351286923,608469776,2089484620,3610856484,4229202447,1150025727,3296934948,1600019292,3224486749,1108129551,1192003942,956416131,3924915651,4294966790,649366928,0,3071262769,2305180172,2197833036,4030267840,1609166965,2315255807,666668534,0,673479819,2297116809,807683271,4,4294766569,608487423,816,4242729216,1153957887,143396,3588816896,3355443196,19932228,3909091328,4294966472,807683271,6,4294753257,608487423,1328,4239321344,112984063,3909091328,4294966831,1467,4263897344,79429631,3909091328,4294966811,955,4262586624,45875199,3909091328,4294966791,443,4261275904,3296985087,1543014748,3277676382,828163203,1600019392,2425406301,2425393296,2425393296]*) ; -O3 (paddNullDel) paddNullDel := [1398167381,9235585,3029008384,45092,267814144,365700,615287552,168,941900999,0,1076118727,0,1009009863,0,649366928,0,1009009803,822086797,223645120,981689856,3910104320,1601,649366928,0,1485691017,1015244289,4101308506,2298658947,2301109340,21767236,608471488,48792400,1411662985,1076118667,2888088715,16777216,2311520704,1715741764,251674499,381828,2344628480,3945276508,649366793,0,1888350345,1015244289,4101308535,2298658947,2301109340,2301895796,22553668,608471488,48792412,1612989577,1344554123,1210340489,807685257,2334393481,10757252,285147136,807685259,1150141065,3258519565,2467287177,254813252,807689398,2299576451,2335188052,961029204,3230863298,2215625480,1296,673471627,252640131,328582,3352725760,4727876,2197815296,4035514342,3640125649,956817539,3276214232,2215624837,130,2333259535,2200970332,2305163768,3968077587,251658245,34428087,1711470723,251810697,379268,1421283072,4169335821,1401513475,2793672452,251658245,101536951,1711601795,252072841,361348,1421283072,4169336845,1401513477,1619267336,251658245,168645815,1711798403,252334985,343429,1421283072,1153895437,477220,2305163264,1552616531,3733530660,3221341737,2314753677,3243254900,1921844202,18124033,807683075,1955186993,3871418404,2313814275,2338595956,1714693236,2197974799,3263365569,281051920,4030730511,673467451,1284237682,1149985828,1552500772,1955145764,3355522084,1344556089,10716175,1284177920,1955281956,344797220,1421283073,2305163349,1351435796,609499393,2189823784,2298478592,265355723,5065911,1443662182,956453005,1982342228,31033708,1287065553,2305163341,1351439884,609499395,2304144936,265355737,5065911,1443662182,956584077,1982342228,31033664,1287065553,2305163341,1351439884,609499397,2301261352,113279961,1144639745,3071223844,1711295820,1985350793,608996116,18124092,807685259,1431615247,344548864,608471873,608996144,1725641044,2332564617,2304517188,2223711236,42020,2333146880,11281548,1955266560,3280552996,2366657421,957362500,3230863299,2467288889,264374466,211844,609520384,251298612,53380623,4186505216,2299519363,4159230408,132154328,1192218681,2244555202,2156138432,251658240,4169340855,327771649,59409423,2357919744,44068,49840896,3071276937,1711419732,251810697,222596,1421283072,4169335865,1401513475,1233391364,251658243,104420535] paddNullDel.push([1711601795,252072841,208260,1421283072,4169336889,1401513477,1300500232,251658243,171529399,1711798403,252334985,209285,1421283072,129567801,1711276032,2332840841,2301895796,29829623,4166487488,1344568457,2365844161,3526427002,673479817,2298734529,2370315388,1141048124,2214806564,44068,1863280128,29524744,2198914947,286200000,1413083215,3916900388,1210350731,874804361,3355572361,1344568379,10781711,2089484288,3029024804,44068,118787328,1444198159,1125419366,956387469,255075412,33158,386698496,1309456143,1393330534,956453005,1983128660,973901165,1309456143,1393330534,956518541,1983128660,386698585,1309456143,1393330534,956584077,1983128660,386698565,1309456143,874804363,1393330534,956649613,2368698070,3163232012,44068,113279744,3071264313,2305183500,376853260,1076133003,2332497037,11281596,3071213568,2305185556,1149977364,3375456292,1277457547,2082765965,1009021953,2015655053,51153254,2686747787,2332033024,22553676,2336236620,608996096,611617072,612141324,273713936,69487753,136598665,76087435,612666148,164,2198360319,24913020,2215626377,172,2753856651,3338665984,795652,285147136,2082755723,807685259,199,1485373440,2312275208,1953825864,2686762123,2332033024,2339906636,2299693847,4169763332,1153896587,11300,3677421568,2333360779,3229814858,608471297,339904808,673475807,673467529,740580489,673475807,3641199324,3723091913,2204727256,20456516,941900939,2955183161,251658240,4294611845,2361688575,3087007744,1,1566531163,7769539,2223703689,40996,2425744128,2520205,2299019403,2223711236,42020,72417024,807683211,2334393481,10757252,1358888960,140413188,1988993515,666668288,0,2753856651,2298478592,2332304452,10495108,76087296,612666148,164,2332840191,10495164,126418944,4294929129,7769599,673471627,807685259,3062743089,0,1110750991,1093962086,956416131,3924915651,4294966401,874804363,3062743089,0,1192539919,1125419366,956416131,3924915654,4294966866,1612989639,2,1545880775,4,1478771911,2,874792135,1,4294590441,608487423,596,608487168,1104,608487168,588,608487168,296,4190562560,79298559,3909091328,4294966523,953,4243712256,45744127,3909091328,4294966503,441,4242401536,112852991,3909091328,4294966483,1465,4241090816,1153957887,411684,1552613376,3353946148,3355443194,88613956,2332033024,3911722076,4294965942,1210336455,4,673471627,4294616553,608487423,840,610044672,4204063016,1153957887,149540,1552613376,2213095460,3355443194,21505092,2332033024,3911722076,4294965874]*) pcopyFromHT := [2333928579,2334401620,2301895748,2332828756,2300585044,2332566612,1418265680,277546020,4280554633,28837968,2197815296,2428705988] pgetFromHash := [609520467,608471820,610044680,2416216848,896843909,1946286979,2231405360,2200728768,662045179,442,2416700160,2520205,192207417,143378569,2231485059,972125641,47827,1158610944,834886594,2428722112] pnext := [1398167381,2333928579,2335188060,2335450220,2335712380,2335974516,4232416019,1913668155,3342723865,130119,1166737408,2199096316,1166606784,272775676,1334519414,608471548,608995588,2298645256,3607045124,3547644037,33310595,1528611971,3277676382,2520205,823968899,1600019392,2425406301,2425393296] } else { pnewTable := [1398167381,955024200,611592463,1221495072,2303513993,672097991,2669043,3539927040,1220576584,1786037129,3242783113,3590259681,1220576584,1517552521,678753925,838815373,3787540690,1712384771,8658703,0,1208191816,1208533635,3343436345,4100,3967090688,2149876875,4060086272,275976463,142313800,3340268425,7235,1133051904,3632875552,611592207,3296938016,1600019256,3224486749,2425417451,2425393296,2425393296] pdestroy := [1465209921,2202555222,2303205612,294340822,2345437513,3380942922,3979428724,4202255,2298645324,478890472,3682945216,2422614132,1211861832,4278733707,2336753750,1459556427,3649652744,4294674760,2236090454,1239512575,2334397579,3313702986,1926052097,176900291,1208506111,1225279115,1210322059,1528874115,1096638302,3774826588,2425393296,2425393296] prehash := [1413567809,1398167381,955024200,1222084936,2303201675,541756366,138578764,2283572033,2244512072,243535835,2197815297,267518400,2299550224,608471513,395003936,1210079231,2303246469,4001632197,1207959552,1250629259,474123032,1166657925,2927890204,1157627904,2337072177,3767092226,3222571853,265454925,35716,1787514112,445336840,182089,1090519040,5093135,264865126,42116,1103114496,440,3375449344,4202255,3250751812,255919586,692373679,3498656194,22121793,255969281,5590199,1725008201,3698706821,4093104689,3242774665,55051232,2336751685,3531950096,1424689525,4202255,1220708680,2236088971,1291154880,2236420745,3666431451,4286285071,2336817151,407538454,29655873,265042241,4294923650,176900351,1208506367,1476333195,3901310984,952402760,1566531163,1564564545,2149519299,0,3943729484,3955241401,1220555157,1530446979,1096638302,3277668700,2425393296,2425393296] remove := [1413567809,1398167381,686588744,414650181,1221495112,1164367753,2215631749,231,3551989569,441,1170223360,2422657585,30519055,3251276240,3391686114,2369900937,2303263058,747456722,3071230226,2238074900,1222473170,3526430347,2300080631,294340816,3257699660,6130505,266044744,41604,3828434176,1221756229,1946700683,960783916,825062681,3956421056,2149519128,0,1287065412,2202534401,1164313280,1962937403,29524751,1976711492,1015244519,578027561,1224969032,2236144777,1208317120,3035349897,696,3296937984,1600019240,1096565085,2236466013,59459812,2303281268,1476338692,1267419144,139984656,4292446536,2336753751,476611334,112641,2202533888,1583032516,1547787615,834886977,1170223597,1089065521,838860799,3296938176,1600019240,1096565085,2303312733,2336751685,3001747531,2425393296] pput := [1430345281,1465209921,2202555222,1097220332,1207974275,2303250313,3314109654,265128269,84612,3955241216,2149519113,0,1351473289,2202101249,21884,1976797512,38309359,4291363144,3297331478,2422652977,3229860489,3071230209,956323148,2302764760,3967177740,1208453960,1009013901,608996684,1082868792,1418283032,2303205412,143345898,2198886143,20718716,264603977,49028,1620224,385810432,8225638,3330885888,13992975,3224436736,258345195,17439,1351473289,2088986113,1207959637,4034253705,1208109197,385861889,258396721,17439,3263418761,3071230977,956321092,2302961370,3967174660,138840393,1009009803,444233,1291845632,2232444553,1296397504,1207989641,258348939,258392303,1116457455,29393692,705644786,474122688,4061676171,3358199624,1247350770,789538320,828143553,3296938176,1600019264,1096565085,3277734237,4202255,2332527432,1211638868,2303459467,2951467060,273189704,3087554303,1,275089741,1086620488,1566531163,1564564545,3116588609,2,3437878065,3120562174,2,1072290609,1224736767,2303259273,408354809,3087501640,4294967295,2425394155,2425393296] pget := [1223459656,1208060744,1009011853,1288866121,941902989,1153599820,1209548939,539249801,1091078984,823153407,612139986,74776892,273713992,1221626184,3276326019,2425393296] pfindKey := [1398167381,1209710351,1210348683,1725139273,2215631749,172,3218323215,1,826654769,3618574290,4203335681,688251585,1104644602,1224823437,2370359945,255922732,1716720823,3715486341,4148286001,1221626352,1208213697,1090585739,113709449,0,1958774088,3531949418,138971980,1097214836,762648891,3375485489,258349035,17439,1152847685,2202534417,1164313282,1964180539,29459216,1976645956,2202101479,1946167612,277563416,1959953736,3498657797,113752043,2,1566531163,17221571,1526726656,3277676382,3224497457,826659377,830794706,2430725056,2425393296,2425393296,2425393296] ptraverse := [1447122753,1413567809,1398167381,1491895112,4130462513,1222084936,2303267211,3314109903,2345437509,3380942922,18056207,2337013760,1290832130,12915853,1224736768,1287662731,1210340489,267224392,59780,4130424064,612666184,192,1208075139,1209030027,1158172043,1955193225,2302746660,1149847768,4282460196,4294476757,8750095,578682880,1853145221,251787395,33669,1166755840,4001974528,264275272,37764,3314108416,4169379563,28852734,1962934272,1166755939,1149846528,2336769060,2303199309,4281869380,2336753751,1476333645,3918088200,1292392447,2336814725,1144529988,1143227531,2303276916,395004166,18639491,1958774085,4294883495,2202599423,1583044804,1547787615,1581342017,1170431809,2783690801,8658703,0,3957885256,395004296,608996168,311117896,168069448,778484715,8658703,0,2333576009,3330480202,265173249,4294897026,112895,2867527680,2425393296,2425393296] pfindVal := [1398167381,414650177,266044774,37252,3526444288,21138753,1015234918,2303262784,881674434,1223521536,1116410251,1958774040,982206561,1208084611,147287181,1293912908,1165286277,1305642309,1947224971,960587308,825128217,3956421056,2149519128,0,1287065409,2202534401,1097204416,1962937403,29524752,1976711492,2202101479,1946169660,462114072,1977320781,3347269819,4013508616,3224480373,1566531163,1133201859,1600019208,4130456413,3922866501,4294967163,2425393296] pmultPut := [1447122753,1413567809,1398167381,2028766024,2336807729,14689468,2303197184,12592268,2303197184,13116564,2303524864,3465104580,3548971755,1401804937,1015244289,4067754055,608472392,3071231080,266044735,992232597,114241,3979411456,608471368,1150109776,826633252,3979429312,608471368,2035544,88378691,3246999808,79105857,3229967940,1147539572,2215639097,638,29393729,1164369643,192282501,992246912,4068806400,2231369729,608487387,60,3800370944,822083585,356814290,3263777024,1174714127,1958774118,960783901,3783528440,2197815297,1150091714,2303262741,79105986,3229967942,1164370805,192282501,992246912,2072317696,2231369730,1938100187,1207959554,3357836427,1124073472,33574029,1210340489,608471364,1141964608,1076118667,1221036361,1418445193,2302953508,3229959656,89951559,2417652736,2210498881,2202534336,256312001,1716260023,4266232132,1975728449,3230221543,608471364,3224454472,76105062,2223720519,51236,307006720,609519874,1141964608,1210336395,1076122763,834898249,2149519296,0,347277,213323588,2210498894,3258515904,210322790,2313777995,29962704,2302764765,2336768780,12592260,3573612544,609520456,1418544472,2303459357,1279272028,1344556171,1191217992,1141910669,1209548939,539251849,1224378700,2336753803,13116548,1358888960,612139792,2337014124,255861852,102276,1149847552,2336770084,13116548,414777344,1275068416,1076124809,1418399999,2337041444,1212163164,199,2303459328,3531933816,274237772,609520456,3548712776,1207959552,3223622795,2332033024,1214784588,2336756363,76105746,2223720650,49188,4010763776,4010763968,277563593,2199667339,1223819712,2311072271,1116412994,256438808,267569194,1712343641] pmultPut.push([264318735,88711,608471808,264275260,80005,3071230976,3224454463,4294826985,1103114751,1153941505,80932,216596480,1728053246,8658703,0,2215631749,4294966851,258392113,17439,21531972,168594755,264800588,1716391095,1326201154,19301647,960757760,495325131,1711276033,3631597957,264976708,4294838916,1284195583,2235907108,25130185,4261013954,2303262719,4282116354,3682992127,17597455,3224436736,1090603149,1208554637,255969417,1716786359,1968116793,1993029918,3531957786,3409568373,1009009863,0,4283794703,1827274751,973078525,608487363,60,1552158464,1728053245,2215629445,4294967095,255967365,21087812,4244826560,2336555007,826025036,3380954560,3224469877,2422622443,273189704,608471368,2223720512,51236,1552501760,1358907428,2223720456,51236,4186524672,2332578047,1211900996,1076122763,610044748,1287685448,252729993,4294887556,112895,2202533888,1583052996,1547787615,1581342017,1220763457,3357840523,1207959552,3223620747,4278190080,2336757842,12592276,2303197184,4270057730,258408447,17439,2215625529,4294966515,264865126,4294893700,1103136255,29770767,4237814210,1153957887,15396,2296971264,2432696316,2425393296]*) ; :( pmultPutConst := [1447122753,1413567809,1398167381,3102507336,822083584,3163244790,73764,2357807104,65572,3599321344,1304660300,49008521,4035565193,1711363725,4668547,826667637,1090776036,2302989449,1418543584,1097204004,4668547,822600,76409205,1157006610,2500846217,1216029764,1344556169,1224051021,1478771849,1157138764,2199369487,3511160800,3640084712,1141366915,255975481,826655815,703410624,2311162306,8397956,1116536832,613714424,156,2198071489,2223571392,33828,65061120,2552530057,1090519040,4280566925,3364471433,21545513,2223589568,34852,4160834560,2082755721,612665672,144,612666696,168,608471368,2223851616,44068,1149847552,2370398244,2303201351,1718625348,8658703,0,88378690,3246999808,1124382479,1958774118,960783888,92540880,1090519043,3942760579,2235918047,2148234706,8070268,67798287,4135911424,67273999,1153892352,15396,2369978368,1140981836,1076118665,5635905,608471876,3330885952,2311227720,3229959656,88902982,1713337344,8658703,0,3229860233,3263383553,213323522,1250518603,3359196414,2302995061,1149846720,826621988,2303026880,2336769540,1096295500,1157649919,2303321221,1149977794,2215591972,376,272665928,264714569,994886291,259007572,3255353491,56132623,2202075136,2249133308,846,2149878923,2231369728,25432009,1090519043,2198320911,1097204217,2215576201,888,1203179329,49906434,1116291430,2038697730,1090519043,71808783,1711536515,71469377,56394767,255918080,2198226871,1097204985,252068489,207748,3071230208,4186114119,2302764549,2215577666,782,1203179329,133792522,1116291430,260378378,1090519043,206026511,1116291430,505868,2088960000,1980136484,2357938245,34852,2626374656,36900,1305620736,822742157,255944393,2199061615,255918529,1209074705,957399683,8660108,3849781248,2552532107,16777216,613170120,156,3263789684,1090633859,1460451087,1724135745,1376553281,3263784566,213323585,2302764631,1351438860,3560521985,255939190,1716980919,1376553281,1090670733,1081529401,213323585,2302764631,1351438860,3560521987,255929974,1716980919,1376553281,1090801805,477549625,213323585,96502615,1724135745,1376553281,255920758,1715934391,1108642113,608471880,29962576,1418284277,21250084,1284197573,2303483940,2302764786,2336752140,16786564,2336751616,1214784588,2336489611,2303203392,1210065996,4282452107,3162706005,44068,2337014016,255861844] pmultPutConst.push([73604,1418284032,2303213604,3108512836,24,5635905,2888078475,1275068416,1076122763,51016,1275068416,2231922825,1351175378,1418414096,2232371236,220,613190472,256,2333182792,11019404,2336751616,76105746,2223720650,65572,4010763776,4010763968,277563593,2199667339,1223819712,2311072271,1116412994,256438808,267569194,1712343641,264318735,65159,608471808,264275260,47749,3071230976,3224454423,4294763497,2035711,2215638661,4294966546,258392113,17439,1090603149,1208554637,3071264905,963007252,745885460,678874681,1976730982,3352181219,3941444,251658240,4294763908,3221307903,1009009863,1,4294759913,2035711,2215626297,4294966466,1959953766,3133179360,1,1103250447,1911144449,2432696316,3909257544,4294967093,273189704,609519948,1149847624,4282466340,2303461461,1442791921,608471816,1418414140,2337030180,2236097620,1384729792,1183059728,3103784959,1,3099885896,1526726656,1096638302,1096630620,3277799774,2089009201,252083236,4294801543,3071230463,2302764551,112642,3219718144,1224736765,2395275,1275068417,4282509961,2336757845,16786572,2303197184,4276349185,3224502271,347541313,2302764615,2202550804,960561600,3924654020,4294966764,1153941553,80932,21037056,4227131840,96010239,3909091328,4294966538,1208,4244695296,112787455,3909091328,4294966518,440,4243384576,62455807,3909091328,4294966498,696,4242073856,2425421823,2425393296]*) pmultPutNoDel := [1447122753,1413567809,1398167381,2565636424,1140850688,2397323,1224736769,2303249801,2223590614,61476,3481881856,608487240,1080,3531949312,3224444020,4202255,2022556297,2202101249,2298500924,32601592,1149847744,2303539236,1308133884,2202140297,3511226340,3707193836,132416321,1157380417,837240591,3760801005,610568516,608471388,149455720,2198071489,1149829568,3770770468,608471299,4282879340,2313169220,1147151428,21553289,1149847744,21788708,1149847800,2370400292,2303201351,1213211716,2284094605,1207959552,1076118665,612666696,140,608471368,1223199048,2303246337,2483243202,61476,981689856,830738176,1140850691,2395275,1157627905,2232404357,256,103058765,1015234918,2215575588,816,609519944,309552,385810432,608996168,3347663160,2336757503,1211114580,3071263625,1725051138,822577473,2302764736,255918663,1713636535,1711428489,2336818057,2336751685,2202543180,2337014213,1279272012,2336553609,2303203392,1210065996,1459554443,616334096,140,3297331457,37913615,414777344,4278190080,2223719446,35876,13060096,0,142117196,274237768,264275269,134021,1435191552,613190400,136,1209174856,1237976201,1711297931,1723920143,2345266959,3229817922,256438785,1116323882,407014172,705644786,1494217416,258347082,2249179439,4294967021,1290963272,1459612041,1166625048,4275824896,258408447,17439,609519944,309552,385810432,608996168,3347663160,2336757503,1211114580,3375481737,3071278981,2302764546,1097204303,2215577481,4294967062,610024264,1133332560,3264417552,264649033,3255353491] pmultPutNoDel.push([28476431,4286775296,2844135180,2332033025,2237408332,2105806793,1090519041,2198255375,2305163769,4253290243,1090519041,38188815,1711470979,251806601,134020,3071230208,4186113094,1133078019,3917745924,1090519041,105297679,1711602051,252068745,108420,3071230208,4186114118,1133078021,2307133192,1090519041,172406543,1711798659,252330889,103301,3071230208,2305166406,129502275,2197815296,106964092,2336767606,1282942028,1881427083,2370622001,3375434500,1863270758,3246592260,286212353,2202537988,1278939330,3899810852,1814318219,1278855169,2215602212,4294966830,4202255,3229860489,3071230209,3342423564,1393330534,4262757903,3263823871,213323585,210331222,22056275,2249185081,4294966782,213323585,210331222,38833491,2249185081,4294966762,213323585,210331222,55610707,2249185081,4294966742,213323585,210331222,72387923,2249185081,4294966722,213323585,96502614,2305214265,2249151244,4294966702,347541313,344548934,4255181123,258408447,17439,604277065,4294835945,2149519359,0,273189704,1275614975,1459616137,1552501000,4276686884,1728053244,8658703,0,2089009201,252076068,4294899079,3071230463,59336198,440,4281919744,2422669311,255967281,1715868855,1212355721,956416131,3924785095,4294966578,8658703,0,440,3296806912,152,1566531163,1564564545,1598119489,2149519299,0,3790323761,1464,4270713088,2422669311,1208,4269926656,258408447,17439,1720,4268878080,258408447,17439,440,4267829504,258408447,17439,952,4266780928,258408447,17439,696,4265732352,2425421823,2425393296]*) pforEachVal := [1447122753,1413567809,1398167381,1491895112,948126054,3481880832,613714248,168,1288079692,3089403017,251658240,110468,2379952384,2204500291,1207977532,2370356105,4017422380,1158122313,826663985,407407606,2215627141,144,616335692,160,1290242373,2686755979,1140850688,2337075849,1015891968,213,2089371648,2336831524,2236141628,1163425023,258403633,17439,2336807813,812912727,1711453967,812975673,3375480881,778443755,8658703,0,1152847684,2202534402,1147536064,1963328571,29459215,3900037433,708608870,2419028992,1212123976,3094740869,604277577,1092110475,1090635395,2205339193,440,3296937984,1600019288,1096565085,1096696157,2336801631,13116548,2202075136,2336752071,2336491599,12592268,2302935040,1159734388,2303260809,4280820804,12067988,4169334784,2206470143,2113929216,1958774037,33063860,4283335951,2303328255,1066092797,4169370091,113406,2232352768,4294967096,2298973000,1212949588,1208504203,1076118665,612666184,168,1208504575,2820965515,1207959552,4279259019,2336753744,11019396,2303197184,139526137,1223525709,1076118667,1277449355,2303270004,2336817221,1770202124,3531931932,2303207541,4280150471,3526492159,2336857835,2336760844,1211638908,2303199627,2336831748,1770202124,3531931932,4273526900,3925868543,4294967053,3677482289,4294859753,2425393407,2425393296] pclone := [1447122753,1413567809,1398167381,1491895112,1208060744,2686749833,1224736768,267573129,1276139536,2332573835,1082857544,608471328,311117856,542637889,1220576584,2303248009,255337540,339844,2223720448,40996,9127936,2333624459,3380943952,253515401,330628,608487168,76,4270411008,1277449355,1291881292,1221602443,13972621,1207959552,807695497,267224397,259204,1620224,826605568,385827327,139823945,3955525961,4287185155,1106807108,1711374221,4340867,2336878453,3677425749,2422605035,3632919433,1711371149,4340867,210629237,385827135,1211501709,4282500489,268403990,110468,1435191552,1250773000,3443083280,273517896,3230863169,264911176,138527123,3380875208,2197815299,2249133311,960,1104316745,1225777795,4148816593,3800252890,4198056199,3611758404,2235943217,259552466,2202077879,2305163770,2215575629,1062,38450959,49972033,38635878,67798031,3071213568,2202076234,2305164282,2215576653,1006,105559823,83526465,105744742,64128015,3071213568,2202077258,2305164794,2215577677,910,172668687,133858113,172853606,57836815,3071213568,2305166410,129567821,1090519040,692452233,3515434455,1171466565,1157120909,1143233673,65585473,29393729,117408577,3306982726,0,610044228,1295742536,826657025,3677439442,171740494,1726546249,74387267,3280158999,286212865,2202603780,960827586,1156084419,1210342539,1155072324,1143233593,8553487,2302738432,3071231688,1181106700,4541577,21073220,1992767812,3071231595,1181106700,4541577,37850436,1992767812,3071231575,1181106700,4541577,54627652,1992767812,3071231555,1181106700,4541577,71404868,1992767812,3071231535,1181106700,4541577,88182084,1992767812,3071231515,3246604812,1724856582,1162643782,252278272,1716130999,5067913,2215638661,400,274041673,273190216,1221212488,1091586701,1220580111,2467285049,3355984321,32670735,4269998080,3917877004,1224736769,2202129033,3511226338,3673639402,132285249,1156725057,836126479,3531949513,3071244148,4202905866,143222273,38306831,3071213568,2202075722,2305164026,2215576136,556,72005391,66749249,71862630,34636815,3071213568,2202076746,2305164538,2215577160,500,139114255,100303681,138971494,29656079,3071213568,2202077770,2305165306,2232355400,424,206223119,206080358,1977,1157073152,2303054633,3609806033,4165438788,65585473,29393729,1174862723,12926093,1979711488] pclone.push([3372305712,1171403077,2370493233,21563932,256009921,1091765359,1124189059,285479183,281183049,1925396805,4177609960,1962883393,3364438395,213323590,2303092290,2370060300,960758081,1181054662,1108129551,210323046,1099777088,3325641730,256266870,1715604663,1074563398,54627652,1992702276,3071231551,1181106700,1145048201,1141129613,745981497,213323590,2303092290,2370060300,960759105,1176073926,1108129551,956744067,2303092430,141967372,1242871567,1209305446,611617608,1149847864,2336755748,1227891780,2360519,1224736768,136604809,7179085,1208353608,2236092555,3909907922,148,4202255,1220708680,2236088971,1291154880,2236424841,444927981,1224736764,2686747787,1207959552,1217069195,608469784,1955266892,3459861540,4225401359,2336817151,1211638852,1532544131,1096638302,1096630620,3277799774,4202255,256166193,1716126903,1208256836,29459272,4000828985,4294927337,2149519359,0,256166193,1716126903,1296337220,3246606336,2010069249,4255836653,258408447,17439,3911223628,4294967158,1721,4267436288,96075775,3909091328,4294966865,1721,4237420800,96075775,3909091328,4294966407,1209,4264814848,62521343,3909091328,4294966825,697,4263504128,28966911,3909091328,4294966805,1209,4233488640,62521343,3909091328,4294966347,697,4232177920,28966911,3909091328,4294966327,3924855112,4294967075,485081137,2432696319]*) paddNullDel := [1447122753,1413567809,1398167381,2028766024,1154320717,3760491659,1207959552,3223620745,1207959552,3357840521,1291845632,2235942025,3951300553,1207959553,1747207309,3352791368,3155012,1157627904,826668593,1149847807,2370326564,1215046724,1478771849,4202255,838371652,2202101449,1962951740,30337287,3246981120,1174487437,1714947213,1144816451,3263777792,3230002293,28476431,21495808,40996288,608471368,4035527744,2088976742,2298478661,2369528948,2215589388,448,49011505,1133364105,210585089,2202232368,19836,1976076621,264275435,106372,46367488,2378170696,2303204140,1145578564,941900937,874796169,1418401791,2336502820,1211638852,2303248009,4169745601,4202255,2210498881,2202534336,256312001,1716260023,4266232132,3900035129,608471880,1149846592,826618916,3918088384,76104806,1142423302,874792075,1220905288,2302984841,2035696,3229860233,3263383553,3071230210,1711295820,1157515913,3900031033,608471880,1103704392,2336808449,1146627164,1009024003,1290963272,1344556171,88901990,2223720448,49188,9127936,406883140,610044232,143345696,2198886399,23864444,264472904,65412,1620224,402587648,1814320267,51016,1207959552,1208512649,2232445065,3448049618,1207959552,3223630987,2332033024,1214784588,2336757387,76105746,4035528906,1712360264,1723920143,2345266959,3229817922,256438785,1116323882,407014172,705644786,1494217416,258347082,2265956655,180,807683203,608471809,612645168,224,4265510159,28901375,1207959552,1534641283,1096638302,1096630620,3277799774,8658703,0,1223723332,1076118727,2,1209,2202101248,17788,1009009863,2,22515009,4266034447,258408447,17439,608487240,584,310528,45809664,1157627904,3909174925,4294966867,4202255,1208191304,3223618699,3909091328,4294967100,273189704,1208506367,1476391305,1804158984,4283885840,778502143,8658703,0,1224378696,3223620747,4278190080,2336757847,12592308,2303197184,4281264390,2425421823] pcopyFromHT := [686588744,608471880,3364440408,1221691721,2336753803,1358891088,112656,2202533888,2428709060,2425393296,2425393296,2425393296] pgetFromHash := [2336805513,2236141828,1095201984,1946286211,9128001,1958774088,4169351479,3123803649,1,778441451,8658703,0,1958885700,3364440078,2198375240,2236088770,1106081225,12243001,1207959552,3284288783,3287531569,2425393296,2425393296,2425393296] pnext := [1398167381,686588744,1208060744,1384896137,3481880828,1287883084,1346096521,3944378904,4232300339,1,2382120587,2336751952,4233529607,1981304889,1133200411,143345916,2236143103,2212132032,1208089667,1529398403,3277676382,2202583089,1583032516,2428722527] } for j, raw in [pnewTable,pdestroy,prehash,remove,pput,pget,pfindKey,ptraverse,pfindVal,pmultPut,pmultPutConst,pmultPutNoDel,pforEachVal,pclone,paddNullDel,pcopyFromHT,pgetFromHash,pnext] ; The order matters. hashTable[j]:=hashTable.rawPut(raw) hashTable.init:=true return } initTable(clone:=0){ this.table:=this.globalAlloc(A_PtrSize) NumPut(clone ? clone : this.newTable(this.size), this.table+0, 0, "Ptr") return } initBoundFuncs(){ ; pnewTable (01) (internal use) ; pdestroy (02) (use destory()) ; prehash (03) (use rehash()) ; remove (04) (use remove(key)) ; pput (05) (use myHashTable[key]:=value) ; pget (06) (use value := myHashTable[key]) ; pfindKey (07) (use HasKey()) ; ptraverse (08) (use forEach(fn)) ; pfindVal (09) (use hasVal() or valGetKey(value)) ; pmultPut (10) (use splitAdd()) ; pmultPutCV (11) (use splitAdd()) ; pmultPutND (12) (use splitAdd()) ; forEachVal (13) (use forEachVal()) ; clone (14) (use clone()) ; addNullDel (15) (use addFromFile()) ; copyFromHT (16) (use copyFromHashTable()) ; getFromHash (17) (enum) ; next (18) (enum) ; this[2] := func("dllCall").bind(hashTable[2], "Ptr", this.table, "Ptr", hashTable.fnLib, "Cdecl") ; destroy this[3] := func("dllCall").bind(hashTable[3], "Ptr", this.table, "Ptr", hashTable.fnLib, "Cdecl Ptr") ; rehash this[4] := func("dllCall").bind(hashTable[4], "Ptr", this.table, "Ptr", hashTable.fnLib, "wstr") ; , key, "Cdecl") ; remove this[5] := func("dllCall").bind(hashTable[5], "Ptr", this.table, "Ptr", hashTable.fnLib, "wstr") ; , key, "wstr", val, "Cdecl") ; put this[6] := func("dllCall").bind(hashTable[6], "Ptr", this.table, "Ptr", hashTable.fnLib, "wstr") ; , key, "Cdecl str") ; get ; 7 this[8] := func("dllCall").bind(hashTable[8], "Ptr", this.table, "Ptr", hashTable.fnLib, "ptr") ; this.icbfn/udfn, "uint", cbid,"ptr",uParams, "Cdecl") ; traverse this[9] := func("dllCall").bind(hashTable[9], "Ptr", this.table, "Ptr", hashTable.fnLib, "wstr") ; val, "Cdecl ptr") ; findVal this[10] := func("dllCall").bind(hashTable[10], "Ptr", this.table, "Ptr", hashTable.fnLib) ; "wstr", keys, "wstr", vals, "wstr", del,"Cdecl") ; multPut this[11] := func("dllCall").bind(hashTable[11], "Ptr", this.table, "Ptr", hashTable.fnLib) ; "wstr", keys, "wstr", vals, "wstr", del,"Cdecl") ; multPutConstVal this[12] := func("dllCall").bind(hashTable[12], "Ptr", this.table, "Ptr", hashTable.fnLib) ; "wstr", keys, "wstr", vals, "int", constVal, "Cdecl") ; multPutNoDel this[13] := func("dllCall").bind(hashTable[13], "Ptr", this.table, "Ptr", hashTable.fnLib, "wstr") ; val, "ptr", this.icbfn/udfn, "uint", cbid,"ptr",uParams, "Cdecl") ; forEachVal this[14] := func("dllCall").bind(hashTable[14], "Ptr", this.table, "Ptr", hashTable.fnLib, "Cdecl Ptr") ; clone this[15] := func("dllCall").bind(hashTable[15], "Ptr", this.table, "Ptr", hashTable.fnLib, "ptr") ; keys, "ptr", vals, "uint", nKeys, "Cdecl") ; addNullDel ; 16 ; 17 this[18] := func("dllCall").bind(hashTable[18], "ptr") return } newTable(sz){ ; Called by initTable() static pmalloc:=DllCall("Kernel32.dll\GetProcAddress", "Ptr", DllCall("Kernel32.dll\GetModuleHandle", "Str", "MSVCRT.dll", "Ptr"), "AStr", "malloc", "Ptr") return DllCall(hashTable[1], "Uint", sz, "Ptr", pmalloc, "Ptr", hashTable.tableSizes, "double", this.maxLoad, "Uint", this.nextSize, "Cdecl ptr") } ; Growing list of array sizes ; Each size is approximately double the previous size. ; All sizes are prime ; maketableSizesArray() relies on this array being assigned above it. static arraySizes:= [2 ,5 ,11 ,23 ,53 ,113 ,251 ,509 ,1019 ,2039 ,4079 ,8179 ,16369 ,32749 ,65521 ,131063 ,262133 ,524269 ,1048571 ,2097143 ,4194287 ,8388587 ,16777183 ,33554393 ,67108837 ; tested, 500 mb empty. 350 ms. ,134217689 ,268435399 ,536870879 ,1073741789 ,2147483629 ,4294967291] maketableSizesArray(){ static init := hashTable.maketableSizesArray() local tableSizes, k, sz tableSizes := hashTable.globalAlloc(this.arraySizes.length()*4) for k, sz in hashTable.arraySizes NumPut(sz, tableSizes+0,(k-1)*4, "int") hashTable.tableSizes:=tableSizes return } makeFnLib(){ ; See hash.h /* typedef struct functionLib { _malloc pmalloc; _free pfree; findKey pfindKey; _rehash prehash; _newHashTable pnewHashTable; //mb pmb; // db } fnLib, *pfnLib; */ local fnLib := hashTable.globalAlloc(5*A_PtrSize) ; Set to 6*A_PtrSize when using db. Can be freed via freeFnLib() (you shouldn't) local pmalloc:=DllCall("Kernel32.dll\GetProcAddress", "Ptr", DllCall("Kernel32.dll\GetModuleHandle", "Str", "MSVCRT.dll", "Ptr"), "AStr", "malloc", "Ptr") local pfree:=DllCall("Kernel32.dll\GetProcAddress", "Ptr", DllCall("Kernel32.dll\GetModuleHandle", "Str", "MSVCRT.dll", "Ptr"), "AStr", "free", "Ptr") NumPut(pmalloc, fnLib+0, A_PtrSize*0, "Ptr") NumPut(pfree, fnLib+0, A_PtrSize*1, "Ptr") NumPut(hashTable[7], fnLib+0, A_PtrSize*2, "Ptr") NumPut(hashTable[3], fnLib+0, A_PtrSize*3, "Ptr") NumPut(hashTable[1], fnLib+0, A_PtrSize*4, "Ptr") ;NumPut(registercallback("mb","Cdecl"), fnLib+0, A_PtrSize*5, "Ptr") ; db hashTable.fnLib:=fnLib return } initSize(target:=0){ ; Picks the closest available size greater or equal to target. local k, sz for k, sz in hashTable.arraySizes { if (sz >= target) { this.size:=sz this.nextSize:=k return this.size } } ; this should be rare. Allocating max size might not even succeed. Not tested. ; Indicies in c source are unsigned int, hence max index is 2**32 (4294967296). throw Exception("The requested size (" target ") is to large. Maximum size is: " hashTable.arraySizes[hashTable.arraySizes.length()] ".",-1) return } rawPut(raw){ ; Called by initBin, for writing binary code to memory. ; Url: ; - https://msdn.microsoft.com/en-us/library/windows/desktop/aa366887(v=vs.85).aspx (VirtualAlloc function) ; - https://msdn.microsoft.com/en-us/library/windows/desktop/aa366786(v=vs.85).aspx (Memory Protection Constants) local k, i, bin static flProtect:=0x40, flAllocationType:=0x1000 ; PAGE_EXECUTE_READWRITE ; MEM_COMMIT bin:=DllCall("Kernel32.dll\VirtualAlloc", "Uptr",0, "Ptr", raw.length()*4, "Uint", flAllocationType, "Uint", flProtect, "Ptr") for k, i in raw NumPut(i,bin+(k-1)*4,"Int") return bin } ; For forEach/Val calloutFunctions:=[] traversecalloutRouter(val,ind,cbid,hash,uParams){ ; Note: this = key. the function is only called via registercallback address. see icbfn. ; typedef int __cdecl (*calloutFn)(unsigned short*,unsigned short*,unsigned int,unsigned int,unsigned int,void*); ; traversecalloutRouter(key,val,ind,cbid,hash,uParams) return object(A_EventInfo).calloutFunctions[cbid].call(StrGet(this,"utf-16"), StrGet(val,"utf-16"), ind, hash, uParams) } setUpcalloutFunctions(udfn,byref cbfn, byref cbid){ ; Used in forEach/Val if udfn is Integer cbfn:=udfn else cbfn:=this.icbfn if isFunc(udfn) && !isObject(udfn) udfn:=func(udfn) cbid:=this.calloutFunctions.push(udfn) return } ; Memory functions freeAllBins(){ ; Probably never wanted. loop 18 hashTable.globalFree(hashTable[A_Index]) return } freeFnLib(){ ; Probably never wanted. this.globalFree(hashTable.fnLib) return } globalAlloc(dwBytes){ ; URL: ; - https://msdn.microsoft.com/en-us/library/windows/desktop/aa366574(v=vs.85).aspx (GlobalAlloc function) ;static GMEM_ZEROINIT:=0x0040 ; Zero fill memory ;static uFlags:=GMEM_ZEROINIT ; For clarity. local hMem if !(hMem:=DllCall("Kernel32.dll\GlobalAlloc", "Uint", 0x0040, "Ptr", dwBytes, "Ptr")) throw exception("GlobalAlloc failed for dwBytes: " dwBytes, -2) return hMem } globalFree(hMem){ ; URL: ; - https://msdn.microsoft.com/en-us/library/windows/desktop/aa366579(v=vs.85).aspx (GlobalFree function) local h if h:=DllCall("Kernel32.dll\GlobalFree", "Ptr", hMem, "Ptr") throw exception("GlobalFree failed at hMem: " hMem, -2) return h } free(buf){ return DllCall("MSVCRT.dll\free", "Ptr", buf, "Cdecl") } ;; Destructor wasFreed:=false destroy(){ ; This is automatically called when the last reference to the table is released, eg, myHashTable:="" if !this.wasFreed && this._isPersistent this.toFile(this.path) if this.wasFreed return this.wasFreed:=true this[2].call() ; pdestroy this.globalFree(this.table) this.globalFree(this.icbfn) } ; Internal tree/print methods. ; Not for v1: /* buildTree(tv,parents,key,val,i,h,uParams){ local id if !parents.haskey(h) { id:=tv.add(h) parents[h]:=id } id:=tv.add(key,parents[h]) tv.add(val,id) return 1 } */ checkIfNeedRehash(n){ ; Make one rehash if it will be needed, to avoid multiple rehashes. if this.count()+n > this.getMaxload() * this.length() this.rehash((this.count()+n) / this.getMaxload()) } _toString(del1,del2,what,toBuf:=false){ ; This is also for writing to buffer, /* typedef struct toStringParams { unsigned short* buf; // string buffer. unsigned short* del1; // key val delimiter unsigned short* del2; // pair delimiter realloc prealloc; // realloc fn memcpy pmemcpy; // memccpy fn unsigned int len; // buffer length unsigned int o; // buffer offset unsigned int dellen1; // delimiter 1 length unsigned int dellen2; // delimiter 2 length int what; // what to get, 0 indicates both key and val, 1, only key, 2, only val. } *pparams; */ static prealloc := DllCall("Kernel32.dll\GetProcAddress", "Ptr", DllCall("Kernel32.dll\GetModuleHandle", "Str", "MSVCRT.dll", "Ptr"), "AStr", "realloc", "Ptr") static pmemcpy := DllCall("Kernel32.dll\GetProcAddress", "Ptr", DllCall("Kernel32.dll\GetModuleHandle", "Str", "MSVCRT.dll", "Ptr"), "AStr", "memcpy", "Ptr") static bin local dellen1, dellen2 if toBuf { ; Use '\0' as delimiter for buffer write varSetCapacity(del1,2,0) varSetCapacity(del2,2,0) dellen1 := what == 1 ? 1 : 0 dellen2 := what == 2 ? 1 : 0 } else { ; Use string as delimiter. dellen1:= what <= 1 ? strlen(del1) : 0 dellen2:= what == 1 ? 0 : strlen(del2) } local uParams ; params to be passed to the calloutFunction, see forEach. varSetCapacity(uParams,5*A_PtrSize+24,0) ; buf numput(&del1, uParams, A_PtrSize*1, "Ptr") ; del1 numput(&del2, uParams, A_PtrSize*2, "Ptr") ; del2 numput(prealloc, uParams, A_PtrSize*3, "Ptr") ; prealloc numput(pmemcpy, uParams, A_PtrSize*4, "Ptr") ; pmemcpy ; len ; o numput(dellen1, uParams, A_PtrSize*5+8, "uint") ; dellen1 numput(dellen2, uParams, A_PtrSize*5+12,"uint") ; dellen2 numput(what, uParams, A_PtrSize*5+16, "int") ; what if !bin ; note, using "this" here because needs to be able to access rawPut if hashTable has been deleted, typically after exitApp() bin := this.rawPut(A_PtrSize == 4 ? [3526448981,3968029526,611617580,612141908,608996164,608602944,2298607747,252978244,36750,2311074048,666668534,0,747488137,21007616,1199342438,4034199806,405040265,2333625995,3355515974,18892291,1003487704,2198803526,132,337935491,252087041,44942,609520384,1208257816,69500041,2300839049,4278723668,1577259094,541494040,1586085889,608471320,138840840,69485705,76351115,604277080,2333103871,1174478918,112664,3296919552,1600019244,3263808349,1711358605,4265704579,2213770496,18097276,4284187919,1153957887,6180,3677421568,4294929385,649367039,0,3238005901,1418265312,1317608484,608471316,2298907396,1459561476,1958774028,609127288,1418397321,1284054052,2088965156,2332103716,2400131150,4294967121,2299669645,2333353044,2369791060,1820936196,1418266660,76088356,274136868,2333886091,51651668,3221297238,2300073609,2332566596,1149830214,109773860,2303722637,1459561476,474909456,52709003,4169341006,407800065,4282156047,109838335,4294898921,3921687039,4294967086,2425393296] : [1465209921,2202555222,2336760044,829957236,3431549439,2346027336,4186126414,829718017,2298670043,2379778515,2204500307,17788,1452011893,809929516,1174654977,30933300,675691512,4186139251,109791233,8949263,2370043904,2370312964,2303217676,542572522,53757579,2336762974,2370048086,2336751620,744392966,1477217608,2334152447,1174484038,112684,2202533888,1583030468,1547787615,2312604099,22515192,1015234918,4050976836,251787651,4294932101,3957010943,2035589,1207964813,1451822731,2232716584,0,1209554687,1484046469,1211649675,1451951753,33129260,4286091023,2370109439,2370322180,2303479820,542572514,53495435,2336763006,2370046038,2336751620,746490118,2014088520,2334152447,1183526998,743834424,2298607747,2215586902,4294967150,3909520200,4294967090,1609154609,2432696319,2425393296,2425393296]) ; bin is toString.c local r := this.forEach(bin, &uParams) ; For loop. local buf:=numget(&uParams,"ptr") local o:=numget(&uParams,A_PtrSize*5+4,"uint") ; the offset if (r && toBuf) ; Caller frees buf. return {buf:buf, bytes:o*2} ; the offset is at the end of the buffer, the buffer is of type short, hence multiply by 2 to get bytes. Now keeps the trailing '\0', it is probably safest because addNullDel searches for '\0' which is not guaranteed to exist at the end of the buffer unless put there. local str ; return if (r && o) str := strGet(buf,o - (what == 1 ? dellen1 : dellen2)) ; Removes the trailing delimiter if buf this.free(buf) return str } _newEnum(){ return new hashTable.enum(this) } class enum { ; Making this ugly improves performance. (a lot) __new(r){ this[1]:=r ; reference this[2]:=1 ; get n:th node in bucket hash this[3]:=0 ; "bucket" } next(byref k, byref v:=""){ static hash, n static dummy := varSetCapacity(hash, 4) + varSetCapacity(n, 4) static phash := &hash static pn := &n static ps := a_ptrsize static ps2 := a_ptrsize*2 static ps2_8 := ps2+8 local node return (node := dllcall(hashTable[18] , "ptr", this[1].table ; tableData** table , "ptr", numput(this[3], hash, "uint") ; uint* hash note: numput returns the "wrong" address, compiled code does hash-=1 (uint) , "ptr", numput(this[2], n, "uint") ; uint* n note: as above for n-=1 , "ptr", hashTable[17] ; pgetFromHash , "cdecl ptr")) ; if node!=0, return true and set key and val ? (k := strget(numget(node+ps, "ptr"),"UTF-16") ; set key , (isbyref(v)? v := strget(numget(node+ps2, "ptr"),"UTF-16"):"") ; set val , this[3] := numget(phash+0, "uint") ; update this.hash (this[3]) , this[2] := numget(pn+0, "uint") ; update this.n (this[2]) , 1) ; return true : 0 ; else return false } } }