summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--generic/tclHAMT.c4
-rw-r--r--generic/tclHAMTObj.c50
2 files changed, 52 insertions, 2 deletions
diff --git a/generic/tclHAMT.c b/generic/tclHAMT.c
index 27b5176..2bed26d 100644
--- a/generic/tclHAMT.c
+++ b/generic/tclHAMT.c
@@ -494,7 +494,7 @@ ArrayMap AMNewBranch(
assert ( idx1 != idx2 );
new->claim = 0;
- new->mask = (1 << (depth * branchShift)) - 1;
+ new->mask = ((size_t)1 << (depth * branchShift)) - 1;
new->id = hash & new->mask;
assert ( (sub->id & new->mask) == new->id );
@@ -556,7 +556,7 @@ ArrayMap AMNewLeaf(
assert ( idx1 != idx2 );
new->claim = 0;
- new->mask = (1 << (depth * branchShift)) - 1;
+ new->mask = ((size_t)1 << (depth * branchShift)) - 1;
new->id = hash1 & new->mask;
assert ( (hash2 & new->mask) == new->id );
diff --git a/generic/tclHAMTObj.c b/generic/tclHAMTObj.c
index c501b01..6b7ec61 100644
--- a/generic/tclHAMTObj.c
+++ b/generic/tclHAMTObj.c
@@ -334,6 +334,7 @@ UpdateStringOfHamt(
*/
static Tcl_ObjCmdProc HamtCreateCmd;
+static Tcl_ObjCmdProc HamtRemoveCmd;
static Tcl_ObjCmdProc HamtReplaceCmd;
/*
@@ -342,6 +343,7 @@ static Tcl_ObjCmdProc HamtReplaceCmd;
static const EnsembleImplMap implementationMap[] = {
{"create", HamtCreateCmd, NULL, NULL, NULL, 0 },
+ {"remove", HamtRemoveCmd, NULL, NULL, NULL, 0 },
{"replace", HamtReplaceCmd, NULL, NULL, NULL, 0 },
{NULL, NULL, NULL, NULL, NULL, 0}
};
@@ -410,7 +412,55 @@ HamtCreateCmd(
Tcl_SetObjResult(interp, hamtObj);
return TCL_OK;
}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * HamtRemoveCmd --
+ *
+ * This function implements the "hamt remove" Tcl command.
+ *
+ * Results:
+ * A standard Tcl result.
+ *
+ * Side effects:
+ * See the user documentation.
+ *
+ *----------------------------------------------------------------------
+ */
+static int
+HamtRemoveCmd(
+ ClientData dummy,
+ Tcl_Interp *interp,
+ int objc,
+ Tcl_Obj *const *objv)
+{
+ TclHAMT old, new;
+ int i;
+
+ if (objc < 2) {
+ Tcl_WrongNumArgs(interp, 1, objv, "hamt ?key ...?");
+ return TCL_ERROR;
+ }
+
+ old = GetHAMTFromObj(interp, objv[1]);
+ if (NULL == old) {
+ return TCL_ERROR;
+ }
+ TclHAMTClaim(old);
+
+ for (i=2 ; i<objc ; i++) {
+ new = TclHAMTRemove(old, objv[i], NULL);
+ TclHAMTClaim(new);
+ TclHAMTDisclaim(old);
+ old = new;
+ }
+
+ Tcl_SetObjResult(interp, NewHAMTObj(old));
+ TclHAMTDisclaim(old);
+ return TCL_OK;
+}
/*
*----------------------------------------------------------------------