diff options
author | Justus Winter <4winter@informatik.uni-hamburg.de> | 2014-05-16 13:25:36 +0200 |
---|---|---|
committer | Justus Winter <4winter@informatik.uni-hamburg.de> | 2014-05-16 13:25:36 +0200 |
commit | 44544936e40a55c6cae9983f1079dd67749347a3 (patch) | |
tree | e8d14a67e361ccc1dcd27a62df6b13155255aa66 /debian/patches/0004-libihash-optimize-lookup-or-insert-operations.patch | |
parent | b39a4dca84393407806cb8a8b0630db1993bc38e (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.patch | 196 |
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 + |