summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordgp <dgp@users.sourceforge.net>2017-10-03 00:28:39 (GMT)
committerdgp <dgp@users.sourceforge.net>2017-10-03 00:28:39 (GMT)
commitff3d10c68ac89905a704d00e6e9e475d02ac6a1b (patch)
treed72bed5a02263925763d436f73e5ee79c592942b
parentcfeba6594a27ea35fed726e15750c49364381ec2 (diff)
downloadtcl-ff3d10c68ac89905a704d00e6e9e475d02ac6a1b.zip
tcl-ff3d10c68ac89905a704d00e6e9e475d02ac6a1b.tar.gz
tcl-ff3d10c68ac89905a704d00e6e9e475d02ac6a1b.tar.bz2
WIP
-rw-r--r--generic/tclHAMT.c42
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. */