diff options
author | apnadkarni <apnmbx-wits@yahoo.com> | 2023-05-04 17:52:06 (GMT) |
---|---|---|
committer | apnadkarni <apnmbx-wits@yahoo.com> | 2023-05-04 17:52:06 (GMT) |
commit | 92dd14e77c81c060ff6ede641885b928afdb9ec3 (patch) | |
tree | 09f32df9e6435a6c51c396584c19e9d284869e2b /generic/tclInt.h | |
parent | 8a45e47c4c3881f7c0db88276adfa26ac9712459 (diff) | |
download | tcl-92dd14e77c81c060ff6ede641885b928afdb9ec3.zip tcl-92dd14e77c81c060ff6ede641885b928afdb9ec3.tar.gz tcl-92dd14e77c81c060ff6ede641885b928afdb9ec3.tar.bz2 |
Refactor reallocation in preparation for experimentation with different growth factors
Diffstat (limited to 'generic/tclInt.h')
-rw-r--r-- | generic/tclInt.h | 43 |
1 files changed, 43 insertions, 0 deletions
diff --git a/generic/tclInt.h b/generic/tclInt.h index 8f87523..4d2f85d 100644 --- a/generic/tclInt.h +++ b/generic/tclInt.h @@ -2872,6 +2872,49 @@ typedef struct ProcessGlobalValue { } while (0) /* + *---------------------------------------------------------------------- + * Common functions for growing allocations. Trivial but allows for + * experimenting with growth factors without having to change code in + * multiple places. Usage example: + * + * allocated = TclUpsizeAlloc(oldSize, needed, TCL_SIZE_MAX); + * while (allocated > needed) { + * ptr = Tcl_AttemptRealloc(oldPtr, allocated); + * if (ptr) + * break; + * allocated = TclUpsizeRetry(needed, allocated); + * } + * if (ptr == NULL) { + * // Last resort - exact size + * allocated = needed; + * ptr = Tcl_Realloc(oldPtr, allocated); + * } + * ptr now points to an allocation of size 'allocated' + *---------------------------------------------------------------------- + */ +static inline Tcl_Size +TclUpsizeAlloc(TCL_UNUSED(Tcl_Size) /*oldSize*/, + Tcl_Size needed, + Tcl_Size limit) +{ + /* assert (oldCapacity < needed <= limit) */ + if (needed < (limit - needed)) { + return 2 * needed; + } else { + return limit; + } +} +static inline Tcl_Size TclUpsizeRetry(Tcl_Size needed, Tcl_Size lastAttempt) { + /* assert (needed < lastAttempt) */ + if (needed < lastAttempt - 1) { + /* (needed+lastAttempt)/2 but that formula may overflow Tcl_Size */ + return needed + (lastAttempt - needed) / 2; + } else { + return needed; + } +} + +/* *---------------------------------------------------------------- * Variables shared among Tcl modules but not used by the outside world. *---------------------------------------------------------------- |