diff options
author | griffin <briang42@easystreet.net> | 2024-04-25 19:49:08 (GMT) |
---|---|---|
committer | griffin <briang42@easystreet.net> | 2024-04-25 19:49:08 (GMT) |
commit | 0ab0962567b070c7108bac68afdfc380e7c994e4 (patch) | |
tree | fdbe8861f602cc61686599843ed21f2c14b4b858 /generic | |
parent | c57e86b1da3ee7f321096f8226f2441776b4b9bc (diff) | |
parent | 30bd5e008251e43f6ecd7a60b81165df12dcb1a2 (diff) | |
download | tcl-0ab0962567b070c7108bac68afdfc380e7c994e4.zip tcl-0ab0962567b070c7108bac68afdfc380e7c994e4.tar.gz tcl-0ab0962567b070c7108bac68afdfc380e7c994e4.tar.bz2 |
Fix dict performance bug: Remove abstractlist extension from dict objtype.
Diffstat (limited to 'generic')
-rw-r--r-- | generic/tclDictObj.c | 182 |
1 files changed, 8 insertions, 174 deletions
diff --git a/generic/tclDictObj.c b/generic/tclDictObj.c index c9ef68d..8c34bb8 100644 --- a/generic/tclDictObj.c +++ b/generic/tclDictObj.c @@ -61,8 +61,6 @@ static Tcl_ObjCmdProc DictForNRCmd; static Tcl_ObjCmdProc DictMapNRCmd; static Tcl_NRPostProc DictForLoopCallback; static Tcl_NRPostProc DictMapLoopCallback; -static Tcl_ObjTypeLengthProc DictAsListLength; -/* static Tcl_ObjTypeIndexProc DictAsListIndex; Needs rewrite */ /* * Table of dict subcommand names and implementations. @@ -131,7 +129,7 @@ typedef struct Dict { * the dictionary. Used for doing traversal of * the entries in the order that they are * created. */ - size_t epoch; /* Epoch counter */ + size_t epoch; /* Epoch counter */ size_t refCount; /* Reference counter (see above) */ Tcl_Obj *chain; /* Linked list used for invalidating the * string representations of updated nested @@ -149,33 +147,22 @@ const Tcl_ObjType tclDictType = { DupDictInternalRep, /* dupIntRepProc */ UpdateStringOfDict, /* updateStringProc */ SetDictFromAny, /* setFromAnyProc */ - TCL_OBJTYPE_V2( /* Extended type for AbstractLists */ - DictAsListLength, /* return "list" length of dict value w/o - * shimmering */ - NULL, /* return key or value at "list" index - * location. (keysare at even indicies, - * values at odd indicies) */ - NULL, - NULL, - NULL, - NULL, - NULL, - NULL) + TCL_OBJTYPE_V0 }; #define DictSetInternalRep(objPtr, dictRepPtr) \ do { \ - Tcl_ObjInternalRep ir; \ + Tcl_ObjInternalRep ir; \ ir.twoPtrValue.ptr1 = (dictRepPtr); \ ir.twoPtrValue.ptr2 = NULL; \ - Tcl_StoreInternalRep((objPtr), &tclDictType, &ir); \ + Tcl_StoreInternalRep((objPtr), &tclDictType, &ir); \ } while (0) #define DictGetInternalRep(objPtr, dictRepPtr) \ do { \ - const Tcl_ObjInternalRep *irPtr; \ - irPtr = TclFetchInternalRep((objPtr), &tclDictType); \ - (dictRepPtr) = irPtr ? (Dict *)irPtr->twoPtrValue.ptr1 : NULL; \ + const Tcl_ObjInternalRep *irPtr; \ + irPtr = TclFetchInternalRep((objPtr), &tclDictType); \ + (dictRepPtr) = irPtr ? (Dict *)irPtr->twoPtrValue.ptr1 : NULL; \ } while (0) /* @@ -2058,7 +2045,7 @@ DictSizeCmd( Tcl_Obj *const *objv) { int result; - Tcl_Size size; + Tcl_Size size; if (objc != 2) { Tcl_WrongNumArgs(interp, 1, objv, "dictionary"); @@ -3854,159 +3841,6 @@ TclInitDictCmd( { return TclMakeEnsemble(interp, "dict", implementationMap); } - -/* - *---------------------------------------------------------------------- - * - * DictAsListLength -- - * - * Compute the length of a list as if the dict value were converted to a - * list. - * - * Note: the list length may not match the dict size * 2. This occurs when - * there are duplicate keys in the original string representation. - * - * Side Effects -- - * - * The intent is to have no side effects. - */ - -static Tcl_Size -DictAsListLength( - Tcl_Obj *objPtr) -{ - Tcl_Size estCount, length, llen; - const char *limit, *nextElem = TclGetStringFromObj(objPtr, &length); - Tcl_Obj *elemPtr; - - /* - * Allocate enough space to hold a (Tcl_Obj *) for each - * (possible) list element. - */ - - estCount = TclMaxListLength(nextElem, length, &limit); - estCount += (estCount == 0); /* Smallest list struct holds 1 - * element. */ - elemPtr = Tcl_NewObj(); - - llen = 0; - - while (nextElem < limit) { - const char *elemStart; - char *check; - Tcl_Size elemSize; - int literal; - - if (TCL_OK != TclFindElement(NULL, nextElem, limit - nextElem, - &elemStart, &nextElem, &elemSize, &literal)) { - Tcl_DecrRefCount(elemPtr); - return 0; - } - if (elemStart == limit) { - break; - } - - TclInvalidateStringRep(elemPtr); - check = Tcl_InitStringRep(elemPtr, literal ? elemStart : NULL, - elemSize); - if (elemSize && check == NULL) { - Tcl_DecrRefCount(elemPtr); - return 0; - } - if (!literal) { - Tcl_InitStringRep(elemPtr, NULL, - TclCopyAndCollapse(elemSize, elemStart, check)); - } - llen++; - } - Tcl_DecrRefCount(elemPtr); - return llen; -} - - -/* - *---------------------------------------------------------------------- - * - * DictAsListIndex -- - * - * Return the key or value at the given "list" index, i.e., as if the string - * value where treated as a list. The intent is to support this list - * operation w/o causing the Obj value to shimmer into a List. - * - * Side Effects -- - * - * The intent is to have no side effects. - * - */ -#if 0 /* Needs rewrite */ -static int -DictAsListIndex( - Tcl_Interp *interp, - struct Tcl_Obj *objPtr, - Tcl_Size index, - Tcl_Obj** elemObjPtr) -{ - Tcl_Size /*estCount,*/ length, llen; - const char *limit, *nextElem = TclGetStringFromObj(objPtr, &length); - Tcl_Obj *elemPtr; - - /* - * Compute limit of the list string - */ - - TclMaxListLength(nextElem, length, &limit); - elemPtr = Tcl_NewObj(); - - llen = 0; - - /* - * parse out each element until reaching the "index"th element. - * Sure this is slow, but shimmering is slower. - */ - while (nextElem < limit) { - const char *elemStart; - char *check; - Tcl_Size elemSize; - int literal; - - if (TCL_OK != TclFindElement(NULL, nextElem, limit - nextElem, - &elemStart, &nextElem, &elemSize, &literal)) { - Tcl_DecrRefCount(elemPtr); - return 0; - } - if (elemStart == limit) { - break; - } - - TclInvalidateStringRep(elemPtr); - check = Tcl_InitStringRep(elemPtr, literal ? elemStart : NULL, - elemSize); - if (elemSize && check == NULL) { - Tcl_DecrRefCount(elemPtr); - if (interp) { - // Need error message here - } - return TCL_ERROR; - } - if (!literal) { - Tcl_InitStringRep(elemPtr, NULL, - TclCopyAndCollapse(elemSize, elemStart, check)); - } - if (llen == index) { - *elemObjPtr = elemPtr; - return TCL_OK; - } - llen++; - } - - /* - * Index is beyond end of list - return empty - */ - Tcl_InitStringRep(elemPtr, NULL, 0); - *elemObjPtr = elemPtr; - return TCL_OK; -} -#endif /* * Local Variables: |