diff options
Diffstat (limited to 'generic')
-rw-r--r-- | generic/tclHAMT.c | 4 | ||||
-rw-r--r-- | generic/tclHAMTObj.c | 50 |
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; +} /* *---------------------------------------------------------------------- |