[Xfce4-commits] <squeeze:master> Added buffer index for faster linked list searches
Peter de Ridder
noreply at xfce.org
Sat Sep 10 21:52:04 CEST 2011
Updating branch refs/heads/master
to 09ac0b105a38ef3a7476f2b84ec9463610aa7e76 (commit)
from 16ac559fa3c66dd607c62cf9d42dad66fd38e693 (commit)
commit 09ac0b105a38ef3a7476f2b84ec9463610aa7e76
Author: Peter de Ridder <peter at xfce.org>
Date: Sat Sep 10 21:46:55 2011 +0200
Added buffer index for faster linked list searches
libsqueeze/archive-iter.c | 74 ++++++++++++++++++++++++++++++++++++++------
libsqueeze/slist.c | 17 ++++++++++
libsqueeze/slist.h | 13 ++++++++
3 files changed, 94 insertions(+), 10 deletions(-)
diff --git a/libsqueeze/archive-iter.c b/libsqueeze/archive-iter.c
index f48f9d9..6288535 100644
--- a/libsqueeze/archive-iter.c
+++ b/libsqueeze/archive-iter.c
@@ -69,6 +69,8 @@ inline static LSQArchiveEntry*
lsq_archive_entry_nth_child(const LSQArchiveEntry *, guint);
inline static void
lsq_archive_entry_flush_buffer(LSQArchiveEntry *);
+inline static void
+lsq_archive_entry_build_buffer_index(LSQArchiveEntry *);
static LSQArchiveEntry *
lsq_archive_entry_get_child(const LSQArchiveEntry *, const gchar *);
static LSQArchiveEntry *
@@ -101,6 +103,7 @@ struct _LSQArchiveEntry
gpointer props;
LSQArchiveEntry **children;
LSQSList *buffer;
+ LSQSIndexList *buffer_index;
};
@@ -1163,30 +1166,55 @@ lsq_archive_entry_flush_buffer(LSQArchiveEntry *entry)
/* free the buffer */
lsq_slist_free(entry->buffer);
entry->buffer = NULL;
+ lsq_slist_index_free(entry->buffer_index);
+ entry->buffer_index = NULL;
g_free(children_old);
}
+inline static void
+lsq_archive_entry_build_buffer_index(LSQArchiveEntry *entry)
+{
+ guint i = 0;
+ LSQSList *buffer_iter = NULL;
+ LSQSIndexList **index_iter = &entry->buffer_index;
+ for ( buffer_iter = entry->buffer ; NULL != buffer_iter ; buffer_iter = buffer_iter->next )
+ {
+ ++i;
+ if ( 0 == ( i % LSQ_ENTRY_BUFFER_INTERVALSIZE ) )
+ {
+ if ( NULL == *index_iter )
+ {
+ *index_iter = lsq_slist_index_new();
+ }
+
+ (*index_iter)->index = buffer_iter;
+
+ index_iter = &((*index_iter)->next);
+ }
+ }
+ lsq_slist_index_free(*index_iter);
+ *index_iter = NULL;
+}
+
static LSQArchiveEntry *
lsq_archive_entry_get_child(const LSQArchiveEntry *entry, const gchar *filename)
{
- LSQSList *buffer_iter = NULL;
+ LSQSList *entry_buffer, *buffer_iter = NULL;
+ LSQSIndexList *index_iter = NULL;
/* the first element of the array (*entry->children) contains the size of the array */
guint size = entry->children?GPOINTER_TO_UINT(*entry->children):0;
guint pos = 0;
guint begin = 1;
gint cmp = 0;
- gchar *_filename;
+ gchar *_filename = NULL;
const gchar *_pos = strchr(filename, '/');
/* remove trailing '/' */
if ( 0 != _pos )
{
_filename = g_strndup(filename, (gsize)(_pos - filename));
- }
- else
- {
- _filename = g_strdup(filename);
+ filename = _filename;
}
/* binary search algoritme */
@@ -1194,7 +1222,7 @@ lsq_archive_entry_get_child(const LSQArchiveEntry *entry, const gchar *filename)
{
pos = (size / 2);
- cmp = strcmp(_filename, entry->children[begin+pos]->filename);
+ cmp = strcmp(filename, entry->children[begin+pos]->filename);
if ( 0 == cmp )
{
g_free(_filename);
@@ -1212,10 +1240,28 @@ lsq_archive_entry_get_child(const LSQArchiveEntry *entry, const gchar *filename)
}
}
+ /* find a start index into the buffer */
+ entry_buffer = entry->buffer;
+ for ( index_iter = entry->buffer_index; NULL != index_iter; index_iter = index_iter->next )
+ {
+ cmp = strcmp(filename, index_iter->index->entry->filename);
+
+ if ( 0 == cmp )
+ {
+ g_free(_filename);
+ return index_iter->index->entry;
+ }
+ if ( 0 > cmp )
+ {
+ break;
+ }
+ entry_buffer = index_iter->index;
+ }
+
/* search the buffer */
- for ( buffer_iter = entry->buffer; NULL != buffer_iter; buffer_iter = buffer_iter->next )
+ for ( buffer_iter = entry_buffer; NULL != buffer_iter; buffer_iter = buffer_iter->next )
{
- cmp = strcmp(_filename, buffer_iter->entry->filename);
+ cmp = strcmp(filename, buffer_iter->entry->filename);
if ( 0 == cmp )
{
@@ -1243,6 +1289,7 @@ lsq_archive_entry_add_child(LSQArchiveEntry *parent, const gchar *filename)
{
LSQArchiveEntry *child = lsq_archive_entry_new(filename);
const gchar *contenttype = lsq_archive_entry_get_contenttype(parent);
+ guint length;
if ( ( NULL == contenttype ) || ( 0 != strcmp ( contenttype, LSQ_MIME_DIRECTORY ) ) )
{
@@ -1255,10 +1302,17 @@ lsq_archive_entry_add_child(LSQArchiveEntry *parent, const gchar *filename)
parent->buffer = lsq_slist_insert_sorted_single(parent->buffer, child, (GCompareFunc)lsq_archive_entry_filename_compare);
- if ( LSQ_ENTRY_CHILD_BUFFER_SIZE == lsq_slist_length(parent->buffer) )
+ /* TODO: cache the length so we doen't have to check every time? */
+ length = lsq_slist_length(parent->buffer);
+
+ if ( LSQ_ENTRY_CHILD_BUFFER_SIZE == length )
{
lsq_archive_entry_flush_buffer(parent);
}
+ else if ( 0 == ( length % LSQ_ENTRY_BUFFER_INTERVALSIZE ) )
+ {
+ lsq_archive_entry_build_buffer_index(parent);
+ }
return child;
}
diff --git a/libsqueeze/slist.c b/libsqueeze/slist.c
index 1f02db2..9af9088 100644
--- a/libsqueeze/slist.c
+++ b/libsqueeze/slist.c
@@ -81,3 +81,20 @@ lsq_slist_free(LSQSList *list)
}
}
+LSQSIndexList *
+lsq_slist_index_new(void)
+{
+ return g_new0(LSQSIndexList, 1);
+}
+
+void
+lsq_slist_index_free(LSQSIndexList *list)
+{
+ LSQSIndexList *next;
+ for(; list; list = next)
+ {
+ next = list->next;
+ g_free(list);
+ }
+}
+
diff --git a/libsqueeze/slist.h b/libsqueeze/slist.h
index dadf676..37f6d8a 100644
--- a/libsqueeze/slist.h
+++ b/libsqueeze/slist.h
@@ -33,4 +33,17 @@ lsq_slist_length(LSQSList *list) G_GNUC_INTERNAL;
void
lsq_slist_free(LSQSList *list) G_GNUC_INTERNAL;
+typedef struct _LSQSIndexList LSQSIndexList;
+
+struct _LSQSIndexList {
+ LSQSList *index;
+ LSQSIndexList *next;
+};
+
+LSQSIndexList *
+lsq_slist_index_new(void);
+
+void
+lsq_slist_index_free(LSQSIndexList *list);
+
#endif /* __LSQ_SLIST_H__ */
More information about the Xfce4-commits
mailing list