diff options
author | dgp <dgp@users.sourceforge.net> | 2017-10-03 00:28:39 (GMT) |
---|---|---|
committer | dgp <dgp@users.sourceforge.net> | 2017-10-03 00:28:39 (GMT) |
commit | ff3d10c68ac89905a704d00e6e9e475d02ac6a1b (patch) | |
tree | d72bed5a02263925763d436f73e5ee79c592942b /generic/tclHAMT.c | |
parent | cfeba6594a27ea35fed726e15750c49364381ec2 (diff) | |
download | tcl-ff3d10c68ac89905a704d00e6e9e475d02ac6a1b.zip tcl-ff3d10c68ac89905a704d00e6e9e475d02ac6a1b.tar.gz tcl-ff3d10c68ac89905a704d00e6e9e475d02ac6a1b.tar.bz2 |
WIP
Diffstat (limited to 'generic/tclHAMT.c')
-rw-r--r-- | generic/tclHAMT.c | 42 |
1 files changed, 41 insertions, 1 deletions
diff --git a/generic/tclHAMT.c b/generic/tclHAMT.c index 14cf6e8..5cf9547 100644 --- a/generic/tclHAMT.c +++ b/generic/tclHAMT.c @@ -684,7 +684,7 @@ ArrayMap AMMergeList( size_t tally; int numList, numSubnode, loffset, i; ClientData *src, *dst; - ArrayMap new; + ArrayMap new, sub; if ((am->mask & hash) != am->id) { /* Hash indicates list does not belong in this subtree */ @@ -704,6 +704,46 @@ ArrayMap AMMergeList( } if (tally & am->kvMap) { /* Hash consistent with existing subnode child */ + soffset = NumBits(am->amMap & (tally - 1)); + + /* Merge the list into that subnode child... */ + sub = AMMergeList(kt, vt, (ArrayMap)am->slot[2*numList + soffset], + hash, kvl, listIsFirst); + if (sub == am->slot[2*numList + soffset]) { + /* Subnode unchanged, map unchanged, just return */ + return am; + } + + /* Copy slots, replacing the subnode with the merge result */ + new = AMNew(numList, numSubnode, am->mask, am->id); + + new->kvMap = am->kvMap; + new->amMap = am->amMap; + + /* Copy all hashes */ + for (i = 0; i < numList; i++) { + *dst++ = *src++; + } + + /* Copy all lists */ + for (i = 0; i < numList; i++) { + KVLClaim((KVList) *src); + *dst++ = *src++; + } + + /* Copy all subnodes, replacing one */ + for (i = 0; i < soffset; i++) { + AMClaim((ArrayMap) *src); + *dst++ = *src++; + } + src++; + AMClaim(sub); + *dst++ = sub; + for (i = soffset + 1; i < numSubnode; i++) { + AMClaim((ArrayMap) *src); + *dst++ = *src++; + } + return new; } /* am is not using this tally; copy am and add it. */ |