diff options
author | Charles Blake <cblake@csail.mit.edu> | 2015-02-06 09:24:20 -0500 |
---|---|---|
committer | Charles Blake <cblake@csail.mit.edu> | 2015-02-06 09:24:20 -0500 |
commit | 65ce08f38c6a8ae05df5529a5b2d51de7aaec2d6 (patch) | |
tree | 5cfe795b7dc047113b5ca273d295229779756e26 /compiler/transf.nim | |
parent | 53f4c7758b0c9d3df562795eeca0a553eb22e219 (diff) | |
download | Nim-65ce08f38c6a8ae05df5529a5b2d51de7aaec2d6.tar.gz |
Add hcode. Re-factor rawGet. Fix infinite loop.
Replace state enum with a cached hash code which has the same memory overhead and locality as the enum, but can really speed things up with non-integer-like keys (keys for which either hash() or == take more than couple cycles, or where the key data is "indirect" and might incur another cache miss). To function as both empty/filled state and a hash code cache, it only needs to be ensured that hash codes are non-zero for any real key. That is done at the one place in the whole file hash() is called. Keep convention clear via isFilled() & isEmpty(). An isDeleted state will no longer be necessary as per below excl/inf loop fix. Since some use sites know hc and some do not, re-factor rawGet into two forms - one with known hash code and one with an unknown HC that returns it. Both forms still return <0 on missing, but returns the much more informative "-1 - index". That return can be quickly inverted by -1 - result to recover the index where insert should happen, provided no modifications are made to the table in the meantime. This protocol retains the prior <0 interface and also makes it easy to avoid unnecessary duplicate search work in procs like containsOrInclImpl (which formerly searched in the initial get and AGAIN in rawInsert). Strip the searching part out of rawInsert to "make it even more raw". swap(s.data, n) a bit earlier so rawGet and rawGetKnownHC can have similar parameter lists and integrate well with rawInsert/code sharing between Set and OrderedSet impls. This PR also fixes infinite looping upon too many deletes. [ The deleted state (aka "tombstone") approach is vulnerable to the table filling up with deleted items which forces giant scans for missing keys which could be anywhere. In the version prior to this PR, table wraparound wasn't even detected yielding infinite loops. ] This PR changes excl() from marking slots as deleted to Knuth algo 6.4R, "local/incremental moveback rehashing" - adapted from Knuth's h->h-1 to the cache-friendlier h->h+1 probe sequence and adapted from "gotos" to a new doWhile template. This method restores the table to a state that would have resulted from pure inserts (in some order). Update nextTry accordingly. Since linear probing can degrade a little faster, 50% rather than 66% may be a better default growth threshold, but users should be able to adjust threshold anyway. Old unit tests all pass. More extensive testing in this module is probably warranted before taking similar enhancements over to collections.tables.
Diffstat (limited to 'compiler/transf.nim')
0 files changed, 0 insertions, 0 deletions