summaryrefslogtreecommitdiff
path: root/debian/patches/0004-libihash-optimize-lookup-or-insert-operations.patch
diff options
context:
space:
mode:
authorJustus Winter <4winter@informatik.uni-hamburg.de>2014-05-16 13:25:36 +0200
committerJustus Winter <4winter@informatik.uni-hamburg.de>2014-05-16 13:25:36 +0200
commit44544936e40a55c6cae9983f1079dd67749347a3 (patch)
treee8d14a67e361ccc1dcd27a62df6b13155255aa66 /debian/patches/0004-libihash-optimize-lookup-or-insert-operations.patch
parentb39a4dca84393407806cb8a8b0630db1993bc38e (diff)
add patch series
Diffstat (limited to 'debian/patches/0004-libihash-optimize-lookup-or-insert-operations.patch')
-rw-r--r--debian/patches/0004-libihash-optimize-lookup-or-insert-operations.patch196
1 files changed, 196 insertions, 0 deletions
diff --git a/debian/patches/0004-libihash-optimize-lookup-or-insert-operations.patch b/debian/patches/0004-libihash-optimize-lookup-or-insert-operations.patch
new file mode 100644
index 00000000..995e9563
--- /dev/null
+++ b/debian/patches/0004-libihash-optimize-lookup-or-insert-operations.patch
@@ -0,0 +1,196 @@
+From 48821cc25fc8f8f30b65c799546e16b8240ac228 Mon Sep 17 00:00:00 2001
+From: Justus Winter <4winter@informatik.uni-hamburg.de>
+Date: Wed, 14 May 2014 16:24:21 +0200
+Subject: [PATCH 04/20] libihash: optimize lookup-or-insert operations
+
+If libihash is used to implement a cache, a insertion is always
+preceeded by a lookup. hurd_ihash_add has to do the lookup again.
+
+Provide a new pair of functions, hurd_ihash_locp_add and
+hurd_ihash_locp_find, that can be used in combination to avoid the
+second lookup.
+
+* libihash/ihash.c (hurd_ihash_locp_add): New function using a
+location pointer...
+(hurd_ihash_locp_find): ... that has been returned by this function.
+* libihash/ihash.h (hurd_ihash_locp_add): New declaration.
+(hurd_ihash_locp_find): Likewise.
+(hurd_ihash_locp_value): New function.
+---
+ libihash/ihash.c | 78 +++++++++++++++++++++++++++++++++++++++++++++++++++++++-
+ libihash/ihash.h | 52 +++++++++++++++++++++++++++++++++++++
+ 2 files changed, 129 insertions(+), 1 deletion(-)
+
+diff --git a/libihash/ihash.c b/libihash/ihash.c
+index 5b7b542..167c872 100644
+--- a/libihash/ihash.c
++++ b/libihash/ihash.c
+@@ -258,7 +258,54 @@ add_one (hurd_ihash_t ht, hurd_ihash_key_t key, hurd_ihash_value_t value)
+ return 0;
+ }
+
+-
++
++/* Add VALUE to the hash table HT under the key KEY at LOCP. If there
++ already is an item under this key, call the cleanup function (if
++ any) for it before overriding the value. This function is faster
++ than hurd_ihash_add.
++
++ If LOCP is NULL, fall back to hurd_ihash_add. Otherwise, LOCP must
++ be valid and may either be obtained from hurd_ihash_locp_find, or
++ from an item that is currently in the hash table. If an item is
++ replaced, KEY must match the key of the previous item.
++
++ If a memory allocation error occurs, ENOMEM is returned, otherwise
++ 0. */
++error_t
++hurd_ihash_locp_add (hurd_ihash_t ht, hurd_ihash_locp_t locp,
++ hurd_ihash_key_t key, hurd_ihash_value_t value)
++{
++ struct _hurd_ihash_item *item = (struct _hurd_ihash_item *) locp;
++
++ /* In case of complications, fall back to hurd_ihash_add. */
++ if (ht->size == 0
++ || item == NULL
++ || item->value == _HURD_IHASH_DELETED
++ || hurd_ihash_get_load (ht) > ht->max_load)
++ return hurd_ihash_add (ht, key, value);
++
++ if (item->value == _HURD_IHASH_EMPTY)
++ {
++ item->key = key;
++ ht->nr_items += 1;
++ }
++ else
++ {
++ assert (item->key == key);
++ if (ht->cleanup)
++ (*ht->cleanup) (locp, ht->cleanup_data);
++ }
++
++ item->value = value;
++
++ if (ht->locp_offset != HURD_IHASH_NO_LOCP)
++ *((hurd_ihash_locp_t *) (((char *) value) + ht->locp_offset))
++ = locp;
++
++ return 0;
++}
++
++
+ /* Add ITEM to the hash table HT under the key KEY. If there already
+ is an item under this key, call the cleanup function (if any) for
+ it before overriding the value. If a memory allocation error
+@@ -327,6 +374,35 @@ hurd_ihash_find (hurd_ihash_t ht, hurd_ihash_key_t key)
+ }
+ }
+
++/* Find the item in the hash table HT with key KEY. If it is found,
++ return the location of its slot in the hash table. If it is not
++ found, this function may still return a location.
++
++ This location pointer can always be safely accessed using
++ hurd_ihash_locp_value. If the lookup is successful,
++ hurd_ihash_locp_value will return the value related to KEY.
++
++ If the lookup is successful, the returned location can be used with
++ hurd_ihash_locp_add to update the item, and with
++ hurd_ihash_locp_remove to remove it.
++
++ If the lookup is not successful, the returned location can be used
++ with hurd_ihash_locp_add to add the item.
++
++ Note that returned location is only valid until the next insertion
++ or deletion. */
++hurd_ihash_locp_t
++hurd_ihash_locp_find (hurd_ihash_t ht, hurd_ihash_key_t key)
++{
++ int idx;
++
++ if (ht->size == 0)
++ return NULL;
++
++ idx = find_index (ht, key);
++ return &ht->items[idx].value;
++}
++
+
+ /* Remove the entry with the key KEY from the hash table HT. If such
+ an entry was found and removed, 1 is returned, otherwise 0. */
+diff --git a/libihash/ihash.h b/libihash/ihash.h
+index 394bcf9..f7ecf1b 100644
+--- a/libihash/ihash.h
++++ b/libihash/ihash.h
+@@ -26,6 +26,7 @@
+ #include <sys/types.h>
+ #include <limits.h>
+ #include <stdint.h>
++#include <stddef.h>
+
+
+ /* The type of the values corresponding to the keys. Must be a
+@@ -198,10 +199,61 @@ hurd_ihash_get_load (hurd_ihash_t ht)
+ error_t hurd_ihash_add (hurd_ihash_t ht, hurd_ihash_key_t key,
+ hurd_ihash_value_t item);
+
++/* Add VALUE to the hash table HT under the key KEY at LOCP. If there
++ already is an item under this key, call the cleanup function (if
++ any) for it before overriding the value. This function is faster
++ than hurd_ihash_add.
++
++ If LOCP is NULL, fall back to hurd_ihash_add. Otherwise, LOCP must
++ be valid and may either be obtained from hurd_ihash_locp_find, or
++ from an item that is currently in the hash table. If an item is
++ replaced, KEY must match the key of the previous item.
++
++ If a memory allocation error occurs, ENOMEM is returned, otherwise
++ 0. */
++error_t hurd_ihash_locp_add (hurd_ihash_t ht, hurd_ihash_locp_t locp,
++ hurd_ihash_key_t key, hurd_ihash_value_t value);
++
+ /* Find and return the item in the hash table HT with key KEY, or NULL
+ if it doesn't exist. */
+ hurd_ihash_value_t hurd_ihash_find (hurd_ihash_t ht, hurd_ihash_key_t key);
+
++/* Find the item in the hash table HT with key KEY. If it is found,
++ return the location of its slot in the hash table. If it is not
++ found, this function may still return a location.
++
++ This location pointer can always be safely accessed using
++ hurd_ihash_locp_value. If the lookup is successful,
++ hurd_ihash_locp_value will return the value related to KEY.
++
++ If the lookup is successful, the returned location can be used with
++ hurd_ihash_locp_add to update the item, and with
++ hurd_ihash_locp_remove to remove it.
++
++ If the lookup is not successful, the returned location can be used
++ with hurd_ihash_locp_add to add the item.
++
++ Note that returned location is only valid until the next insertion
++ or deletion. */
++hurd_ihash_locp_t hurd_ihash_locp_find (hurd_ihash_t ht,
++ hurd_ihash_key_t key);
++
++/* Given an hash table bucket location LOCP, return the value stored
++ there, or NULL if it is empty or LOCP is NULL. */
++static inline void *
++hurd_ihash_locp_value (hurd_ihash_locp_t locp)
++{
++ struct _hurd_ihash_item *item = (struct _hurd_ihash_item *) locp;
++
++ if (item == NULL)
++ return NULL;
++
++ if (hurd_ihash_value_valid (item->value))
++ return item->value;
++
++ return NULL;
++}
++
+ /* Iterate over all elements in the hash table. You use this macro
+ with a block, for example like this:
+
+--
+2.0.0.rc0
+