From 3a5219c6d0c1a85ac3cf7a6b938f724650001a4d Mon Sep 17 00:00:00 2001 From: nicm Date: Mon, 25 May 2020 09:32:10 +0000 Subject: Instead of storing all UTF-8 characters in the extended cell which means that 14 bytes are wasted for each character in the BMP, only store characters of three bytes or less in the cell itself and store others (outside the BMP or with combining characters) in a separate global tree. Can reduce grid memory use for heavy Unicode users by around 30%. --- window-copy.c | 28 +++++++++++++++++++++++----- 1 file changed, 23 insertions(+), 5 deletions(-) (limited to 'window-copy.c') diff --git a/window-copy.c b/window-copy.c index e572eaa8..1efe01d0 100644 --- a/window-copy.c +++ b/window-copy.c @@ -2551,23 +2551,33 @@ window_copy_search_rl_regex(struct grid *gd, u_int *ppx, u_int *psx, u_int py, } static const char * -window_copy_cellstring(const struct grid_line *gl, u_int px, size_t *size) +window_copy_cellstring(const struct grid_line *gl, u_int px, size_t *size, + int *allocated) { + static struct utf8_data ud; struct grid_cell_entry *gce; + char *copy; if (px >= gl->cellsize) { *size = 1; + *allocated = 0; return (" "); } gce = &gl->celldata[px]; if (~gce->flags & GRID_FLAG_EXTENDED) { *size = 1; + *allocated = 0; return (&gce->data.data); } - *size = gl->extddata[gce->offset].data.size; - return (gl->extddata[gce->offset].data.data); + utf8_get_big(gl->extddata[gce->offset].data, &ud); + *size = ud.size; + *allocated = 1; + + copy = xmalloc(ud.size); + memcpy(copy, ud.data, ud.size); + return (copy); } /* Find last match in given range. */ @@ -2630,6 +2640,7 @@ window_copy_stringify(struct grid *gd, u_int py, u_int first, u_int last, const struct grid_line *gl; const char *d; size_t bufsize = 1024, dlen; + int allocated; while (bufsize < newsize) bufsize *= 2; @@ -2638,7 +2649,7 @@ window_copy_stringify(struct grid *gd, u_int py, u_int first, u_int last, gl = grid_peek_line(gd, py); bx = *size - 1; for (ax = first; ax < last; ax++) { - d = window_copy_cellstring(gl, ax, &dlen); + d = window_copy_cellstring(gl, ax, &dlen, &allocated); newsize += dlen; while (bufsize < newsize) { bufsize *= 2; @@ -2650,6 +2661,8 @@ window_copy_stringify(struct grid *gd, u_int py, u_int first, u_int last, memcpy(buf + bx, d, dlen); bx += dlen; } + if (allocated) + free((void *)d); } buf[newsize - 1] = '\0'; @@ -2670,6 +2683,7 @@ window_copy_cstrtocellpos(struct grid *gd, u_int ncells, u_int *ppx, u_int *ppy, struct { const char *d; size_t dlen; + int allocated; } *cells; /* Populate the array of cell data. */ @@ -2680,7 +2694,7 @@ window_copy_cstrtocellpos(struct grid *gd, u_int ncells, u_int *ppx, u_int *ppy, gl = grid_peek_line(gd, pywrap); while (cell < ncells) { cells[cell].d = window_copy_cellstring(gl, px, - &cells[cell].dlen); + &cells[cell].dlen, &cells[cell].allocated); cell++; px++; if (px == gd->sx) { @@ -2738,6 +2752,10 @@ window_copy_cstrtocellpos(struct grid *gd, u_int ncells, u_int *ppx, u_int *ppy, *ppy = pywrap; /* Free cell data. */ + for (cell = 0; cell < ncells; cell++) { + if (cells[cell].allocated) + free((void *)cells[cell].d); + } free(cells); } -- cgit