Attachment "binary.patch" to
ticket [429916ffff]
added by
msofer
2001-06-04 05:21:45.
? binary.patch
? generic/tclBinary_orig.c
? unix/pkg
Index: ChangeLog
===================================================================
RCS file: /cvsroot/tcl/tcl/ChangeLog,v
retrieving revision 1.456
diff -r1.456 ChangeLog
0a1,8
> 2001-06-03 Miguel Sofer <msofer@users.sourceforge.net>
>
> * generic/tclBinary.c: Improved efficiency of splitting binary
> strings into individual characters by adding hash so that only one
> Tcl_Obj per item is created. Makes a huge difference to splitting
> of long binary strings, such as is done in the mime package in
> tcllib. Similar to the solution of [Bug #131523]
>
Index: generic/tclBinary.c
===================================================================
RCS file: /cvsroot/tcl/tcl/generic/tclBinary.c,v
retrieving revision 1.7
diff -r1.7 tclBinary.c
1201a1202,1240
> } else if (((sizeof(char *)) >= (sizeof(long)))
> /* the optimiser should eliminate that first test */
> && (count == BINARY_ALL) && (cmd != 'd') && (cmd != 'f')) {
>
> Tcl_HashTable charReuseTable;
> Tcl_HashEntry *hPtr;
> int isNew;
> long elementVal;
>
> /*
> * Handle the special case of splitting on every long value.
> *
> * Uses a hash table to ensure that each value has
> * only one Tcl_Obj instance (multiply-referenced) in the
> * final list. This is a *major* win when splitting on a long
> * bytearray (especially in the megabyte range!) - DKF/MS
> */
>
> Tcl_InitHashTable(&charReuseTable, TCL_ONE_WORD_KEYS);
> count = (length - offset) / size;
> valuePtr = Tcl_NewObj();
> src = buffer+offset;
> for (i = 0; i < count; i++) {
> elementPtr = ScanNumber(src, cmd);
> Tcl_GetLongFromObj(interp, elementPtr, &elementVal);
> hPtr = Tcl_CreateHashEntry(&charReuseTable, (char *) elementVal, &isNew);
> if (isNew) {
> /* Don't need to fiddle with refcount... */
> Tcl_SetHashValue(hPtr, (ClientData) elementPtr);
> } else {
> TclDecrRefCount(elementPtr);
> elementPtr = (Tcl_Obj*) Tcl_GetHashValue(hPtr);
> }
> src += size;
> Tcl_ListObjAppendElement(NULL, valuePtr,
> elementPtr);
> }
> Tcl_DeleteHashTable(&charReuseTable);
> offset += count*size;