summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYorhel <git@yorhel.nl>2013-06-28 16:32:03 +0200
committerYorhel <git@yorhel.nl>2013-06-28 16:32:03 +0200
commitf3b6a16e3cd2931bb50aa5ff86e6d1d1691b7524 (patch)
treef9428f63cdc30e6b18229264154aa98296c8e670
parentd66abc047b83ff3b5d7fca70e256fe1666bdb9da (diff)
util/list: Re-add hlist_* macros
This is a partial revert of 38d80827ba30059a9a513c45793f853ed59f067f. I also added the respective hp* macros, although I won't be using these for now. I realized why I had implemented the single-pointer list anchor case; It will halve the memory usage of the hash index. With the hlist_ macros, that index is simply a hash set of share_fl_t pointers. Without, it'll be a hash set of struct { share_fl_t *head, *tail; }, i.e. twice as large. The tail pointer really isn't necessary.
-rw-r--r--src/util/list.h27
-rw-r--r--src/util/logfile.c10
2 files changed, 31 insertions, 6 deletions
diff --git a/src/util/list.h b/src/util/list.h
index b883168..dbca564 100644
--- a/src/util/list.h
+++ b/src/util/list.h
@@ -31,6 +31,10 @@
* All macros starting with 's' (e.g. slist_ instead of list_) operate on
* singly-linked lists. The nodes only need to have a 'next' pointer.
*
+ * All macros containing the 'h' (hlist_, shlist_) flag take only a single
+ * pointer variable as list argument rather than a struct. This pointer is
+ * treated as the `head' of a list.
+ *
* All macros containing the 'p' flag (plist_, splist_) accept an additional
* prefix argument. This argument specifies the name of the struct in which the
* 'next' and 'prev' pointers reside. This allows the same element to be in
@@ -89,5 +93,28 @@
#define list_remove(_l, _n) list__remove(_l,,_n)
+/* Like list_insert(), but does not support inserting at the tail of the list.
+ */
+#define hlist__insert_before(_l, _p, _n, _next) do {\
+ (_n)-> _p next = (_next);\
+ (_n)-> _p prev = (_n)-> _p next ? (_n)-> _p next -> _p prev : NULL;\
+ if((_n)-> _p next) (_n)-> _p next-> _p prev = (_n);\
+ if((_n)-> _p prev) (_n)-> _p prev-> _p next = (_n);\
+ else (_l) = (_n);\
+ } while(0)
+#define hplist_insert_before(_l,_p,_n,_next) hlist__insert_before(_l,_p.,_n,_next)
+#define hlist_insert_before(_l,_n,_next) hlist__insert_before(_l,,_n,_next)
+
+
+/* Like list_remove() */
+#define hlist__remove(_l, _p, _n) do {\
+ if((_n)-> _p next) (_n)-> _p next-> _p prev = (_n)-> _p prev;\
+ if((_n)-> _p prev) (_n)-> _p prev-> _p next = (_n)-> _p next;\
+ if((_n) == (_l)) (_l) = (_n)-> _p next;\
+ } while(0)
+#define hplist_remove(_l, _p, _n) hlist__remove(_l, _p., _n)
+#define hlist_remove(_l, _n) hlist__remove(_l,,_n)
+
+
#endif
/* vim: set noet sw=4 ts=4: */
diff --git a/src/util/logfile.c b/src/util/logfile.c
index cc1bd75..fed611d 100644
--- a/src/util/logfile.c
+++ b/src/util/logfile.c
@@ -30,9 +30,7 @@ struct logfile_t {
struct stat st;
};
-static struct {
- logfile_t *head, *tail;
-} logfile_list;
+static logfile_t *logfile_list;
/* (Re)opens the log file and checks for inode and file size changes. */
@@ -76,14 +74,14 @@ logfile_t *logfile_open(const char *fn) {
l->fn = strdup(fn);
l->fd = -1;
- list_insert(logfile_list, l, NULL);
+ hlist_insert_before(logfile_list, l, logfile_list);
logfile_checkfile(l);
return l;
}
void logfile_close(logfile_t *l) {
- list_remove(logfile_list, l);
+ hlist_remove(logfile_list, l);
if(l->fd >= 0)
close(l->fd);
@@ -128,7 +126,7 @@ static void logfile_reopen(logfile_t *l) {
void logfile_global_reopen() {
logfile_t *l;
- for(l=logfile_list.head; l; l=l->next)
+ for(l=logfile_list; l; l=l->next)
logfile_reopen(l);
}