From b5c8b99082ac640bdec6d83f6249389a58d68e9a Mon Sep 17 00:00:00 2001 From: dgp Date: Mon, 25 Sep 2017 01:29:38 +0000 Subject: Add [hamt remove] command and fix more bugs. --- generic/tclHAMT.c | 4 ++-- 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