Artifact [31eedba8ad]
Not logged in

Artifact 31eedba8ade0e454982205d6ea6213983b990ead:

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;