From c007cacd09c850e68a0c84c8f1c7bc82a7252d58 Mon Sep 17 00:00:00 2001 From: Julien Danjou Date: Fri, 27 Jun 2008 12:08:19 +0200 Subject: [PATCH] xutil: make atoms cache an array Signed-off-by: Julien Danjou --- awesome.c | 1 - common/xutil.c | 74 ++++++++++++++++++++++++++++++-------------------- common/xutil.h | 28 +++++++------------ structs.h | 2 +- 4 files changed, 55 insertions(+), 50 deletions(-) diff --git a/awesome.c b/awesome.c index 58b1b198b..3dfc79fa8 100644 --- a/awesome.c +++ b/awesome.c @@ -391,7 +391,6 @@ main(int argc, char **argv) &globalconf.shiftlockmask, &globalconf.capslockmask); /* init Atoms cache and then EWMH atoms */ - atom_cache_list_init(&globalconf.atoms); ewmh_init_atoms(); /* init screens struct */ diff --git a/common/xutil.c b/common/xutil.c index 21241278f..4c0386ef8 100644 --- a/common/xutil.c +++ b/common/xutil.c @@ -40,7 +40,7 @@ */ bool xutil_gettextprop(xcb_connection_t *conn, xcb_window_t w, - xutil_atom_cache_t **atoms, + xutil_atom_cache_array_t *atoms, xcb_atom_t atom, char **text) { xcb_get_property_cookie_t prop_c; @@ -158,7 +158,7 @@ xutil_get_transient_for_hint(xcb_connection_t *c, xcb_window_t win, /** Send an unchecked InternAtom request if it is not already in the * cache, in the second case it stores the cache entry (an ordered - * linked-list). + * array). * \param c X connection. * \param atoms Atoms cache, or NULL if no cache. * \param name Atom name. @@ -166,30 +166,39 @@ xutil_get_transient_for_hint(xcb_connection_t *c, xcb_window_t win, */ xutil_intern_atom_request_t xutil_intern_atom(xcb_connection_t *c, - xutil_atom_cache_t **atoms, + xutil_atom_cache_array_t *atoms, const char *name) { xutil_intern_atom_request_t atom_req; - xutil_atom_cache_t *atom_next; - int cmp_cache; + int l = 0, r; p_clear(&atom_req, 1); - /* Check if this atom is present in the cache ordered linked-list */ + /* Check if this atom is present in the cache ordered array */ if(atoms) - for(atom_next = *atoms; - atom_next && (cmp_cache = a_strcmp(name, atom_next->name)) >= 0; - atom_next = atom_cache_list_next(NULL, atom_next)) - if(cmp_cache == 0) + { + r = atoms->len; + while (l < r) + { + int i = (r + l) / 2; + switch (a_strcmp(name, atoms->tab[i]->name)) { + case -1: /* ev < atoms->tab[i] */ + r = i; + break; + case 0: /* ev == atoms->tab[i] */ atom_req.cache_hit = true; - atom_req.cache = atom_next; + atom_req.cache = atoms->tab[i]; return atom_req; + case 1: /* ev > atoms->tab[i] */ + l = i + 1; + break; } + } + } /* Otherwise send an InternAtom request to the server */ atom_req.name = a_strdup(name); - atom_req.cache_hit = false; atom_req.cookie = xcb_intern_atom_unchecked(c, false, a_strlen(name), name); return atom_req; @@ -205,12 +214,13 @@ xutil_intern_atom(xcb_connection_t *c, */ xcb_atom_t xutil_intern_atom_reply(xcb_connection_t *c, - xutil_atom_cache_t **atoms, + xutil_atom_cache_array_t *atoms, xutil_intern_atom_request_t atom_req) { xcb_intern_atom_reply_t *atom_rep; - xutil_atom_cache_t *atom_cache, *atom_next; - xcb_atom_t atom; + xutil_atom_cache_t *atom_cache; + xcb_atom_t atom = 0; + int l = 0, r; /* If the atom is present in the cache, just returns the * atom... */ @@ -219,35 +229,39 @@ xutil_intern_atom_reply(xcb_connection_t *c, /* Get the reply from InternAtom request */ if(!(atom_rep = xcb_intern_atom_reply(c, atom_req.cookie, NULL))) - { - p_delete(&atom_req.name); - return 0; - } + goto bailout; atom = atom_rep->atom; if(atoms) { + r = atoms->len; + /* Create a new atom cache entry */ atom_cache = p_new(xutil_atom_cache_t, 1); atom_cache->atom = atom_rep->atom; atom_cache->name = atom_req.name; - /* Add the entry in the list at the beginning of the cache list */ - if(*atoms == NULL || a_strcmp(atom_req.name, (*atoms)->name) < 0) - atom_cache_list_push(atoms, atom_cache); - /* Otherwise insert it at the proper position in the cache list - * according to its name */ - else + while (l < r) { - for(atom_next = *atoms; - atom_next && atom_next->next && a_strcmp(atom_req.name, atom_next->next->name) > 0; - atom_next = atom_cache_list_next(NULL, atom_next)); - - atom_cache_list_attach_after(atom_next, atom_cache); + int i = (r + l) / 2; + switch(a_strcmp(atom_cache->name, atoms->tab[i]->name)) + { + case -1: /* k < atoms->tab[i] */ + r = i; + break; + case 0: /* k == atoms->tab[i] cannot append */ + assert(0); + case 1: /* k > atoms->tab[i] */ + l = i + 1; + break; + } } + + xutil_atom_cache_array_splice(atoms, r, 0, &atom_cache, 1); } +bailout: p_delete(&atom_rep); return atom; diff --git a/common/xutil.h b/common/xutil.h index 2bca8718f..3228a0903 100644 --- a/common/xutil.h +++ b/common/xutil.h @@ -32,7 +32,7 @@ /* XCB doesn't provide keysyms definition */ #include -#include "common/list.h" +#include "array.h" #define CLEANMASK(mask) (mask & ~(globalconf.numlockmask | XCB_MOD_MASK_LOCK)) @@ -97,16 +97,17 @@ typedef struct class_hint_t *xutil_get_class_hint(xcb_connection_t *, xcb_window_t); /** Cache entry */ -typedef struct xutil_atom_cache_t xutil_atom_cache_t; -struct xutil_atom_cache_t +typedef struct { /** Atom X identifier */ xcb_atom_t atom; /** Atom name */ char *name; - /** Next and previous atom cache entries */ - xutil_atom_cache_t *prev, *next; -}; +} xutil_atom_cache_t; + +void xutil_atom_cache_delete(xutil_atom_cache_t **); + +DO_ARRAY(xutil_atom_cache_t *, xutil_atom_cache, xutil_atom_cache_delete) /** InternAtom request data structure which may hold the cookie if the * atom is not already present in the cache */ @@ -125,22 +126,13 @@ typedef struct }; } xutil_intern_atom_request_t; -/* InternATom request which relies on a cache stored as a ordered - * linked-list */ -xutil_intern_atom_request_t xutil_intern_atom(xcb_connection_t *, xutil_atom_cache_t **, +xutil_intern_atom_request_t xutil_intern_atom(xcb_connection_t *, xutil_atom_cache_array_t *, const char *); -/** Treat reply from InternAtom request */ -xcb_atom_t xutil_intern_atom_reply(xcb_connection_t *, xutil_atom_cache_t **, +xcb_atom_t xutil_intern_atom_reply(xcb_connection_t *, xutil_atom_cache_array_t *, xutil_intern_atom_request_t); -/** Delete a entry in the cache */ -void xutil_atom_cache_delete(xutil_atom_cache_t **); - -/** Cache list utils functions */ -DO_SLIST(xutil_atom_cache_t, atom_cache, xutil_atom_cache_delete) - -bool xutil_gettextprop(xcb_connection_t *, xcb_window_t, xutil_atom_cache_t **, +bool xutil_gettextprop(xcb_connection_t *, xcb_window_t, xutil_atom_cache_array_t *, xcb_atom_t, char **); void xutil_getlockmask(xcb_connection_t *, xcb_key_symbols_t *, diff --git a/structs.h b/structs.h index e1f7d2080..c7916735c 100644 --- a/structs.h +++ b/structs.h @@ -422,7 +422,7 @@ struct awesome_t /** Last XMotionEvent coords */ int pointer_x, pointer_y; /** Atoms cache */ - xutil_atom_cache_t *atoms; + xutil_atom_cache_array_t atoms; /** Lua VM state */ lua_State *L; /** Default colors */