Introduction
Introduction Statistics Contact Development Disclaimer Help
drw: minor improvement to the nomatches cache - dmenu - dynamic menu
git clone git://git.suckless.org/dmenu
Log
Files
Refs
README
LICENSE
---
commit 7ab0cb5ef0e19352fc5d64ae0d57a5cf4540acbf
parent 0fe460dbd469a1d5b6a7140d0e1801935e4a923b
Author: NRK <[email protected]>
Date: Fri, 7 Jul 2023 17:00:42 +0600
drw: minor improvement to the nomatches cache
1. use `unsigned int` to store the codepoints, this avoids waste on
common case where `long` is 64bits. and POSIX guarantees `int` to be
at least 32bits so there's no risk of truncation.
2. since switching to `unsigned int` cuts down the memory requirement by
half, double the cache size from 64 to 128.
3. instead of a linear search, use a simple hash-table for O(1) lookups.
Diffstat:
M dmenu.c | 1 -
M drw.c | 23 ++++++++++++-----------
M util.h | 1 +
3 files changed, 13 insertions(+), 12 deletions(-)
---
diff --git a/dmenu.c b/dmenu.c
@@ -22,7 +22,6 @@
/* macros */
#define INTERSECT(x,y,w,h,r) (MAX(0, MIN((x)+(w),(r).x_org+(r).width) - MAX(…
* MAX(0, MIN((y)+(h),(r).y_org+(r).height) - MAX(…
-#define LENGTH(X) (sizeof X / sizeof X[0])
#define TEXTW(X) (drw_fontset_getwidth(drw, (X)) + lrpad)
/* enums */
diff --git a/drw.c b/drw.c
@@ -238,8 +238,8 @@ drw_rect(Drw *drw, int x, int y, unsigned int w, unsigned i…
int
drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int …
{
- int i, ty, ellipsis_x = 0;
- unsigned int tmpw, ew, ellipsis_w = 0, ellipsis_len;
+ int ty, ellipsis_x = 0;
+ unsigned int tmpw, ew, ellipsis_w = 0, ellipsis_len, hash, h0, h1;
XftDraw *d = NULL;
Fnt *usedfont, *curfont, *nextfont;
int utf8strlen, utf8charlen, render = x || y || w || h;
@@ -251,9 +251,7 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned i…
XftResult result;
int charexists = 0, overflow = 0;
/* keep track of a couple codepoints for which we have no match. */
- enum { nomatches_len = 64 };
- static struct { long codepoint[nomatches_len]; unsigned int idx; } nom…
- static unsigned int ellipsis_width = 0;
+ static unsigned int nomatches[128], ellipsis_width;
if (!drw || (render && (!drw->scheme || !w)) || !text || !drw->fonts)
return 0;
@@ -338,11 +336,14 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned…
* character must be drawn. */
charexists = 1;
- for (i = 0; i < nomatches_len; ++i) {
- /* avoid calling XftFontMatch if we know we wo…
- if (utf8codepoint == nomatches.codepoint[i])
- goto no_match;
- }
+ hash = (unsigned int)utf8codepoint;
+ hash = ((hash >> 16) ^ hash) * 0x21F0AAAD;
+ hash = ((hash >> 15) ^ hash) * 0xD35A2D97;
+ h0 = ((hash >> 15) ^ hash) % LENGTH(nomatches);
+ h1 = (hash >> 17) % LENGTH(nomatches);
+ /* avoid expensive XftFontMatch call when we know we w…
+ if (nomatches[h0] == utf8codepoint || nomatches[h1] ==…
+ goto no_match;
fccharset = FcCharSetCreate();
FcCharSetAddChar(fccharset, utf8codepoint);
@@ -371,7 +372,7 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned i…
curfont->next = usedfont;
} else {
xfont_free(usedfont);
- nomatches.codepoint[++nomatches.idx % …
+ nomatches[nomatches[h0] ? h1 : h0] = u…
no_match:
usedfont = drw->fonts;
}
diff --git a/util.h b/util.h
@@ -3,6 +3,7 @@
#define MAX(A, B) ((A) > (B) ? (A) : (B))
#define MIN(A, B) ((A) < (B) ? (A) : (B))
#define BETWEEN(X, A, B) ((A) <= (X) && (X) <= (B))
+#define LENGTH(X) (sizeof (X) / sizeof (X)[0])
void die(const char *fmt, ...);
void *ecalloc(size_t nmemb, size_t size);
You are viewing proxied material from suckless.org. The copyright of proxied material belongs to its original authors. Any comments or complaints in relation to proxied material should be directed to the original authors of the content concerned. Please see the disclaimer for more details.