From b264a161738c61cd3f3197f676d7c7780e4ae8e8 Mon Sep 17 00:00:00 2001 From: scottmk Date: Mon, 5 Oct 2009 14:48:24 +0000 Subject: [PATCH] Created a new function osrfHashExtract(). It extracts an item with a given key from an osrfHash, without destroying it, leaving the rest of the osrfHash intact. M include/opensrf/osrf_hash.h M src/libopensrf/osrf_hash.c git-svn-id: svn://svn.open-ils.org/OpenSRF/trunk@1806 9efc2488-bf62-4759-914b-345cdb29e865 --- include/opensrf/osrf_hash.h | 2 ++ src/libopensrf/osrf_hash.c | 50 +++++++++++++++++++++++++++++++++---- 2 files changed, 47 insertions(+), 5 deletions(-) diff --git a/include/opensrf/osrf_hash.h b/include/opensrf/osrf_hash.h index 3c709d5..0f75f71 100644 --- a/include/opensrf/osrf_hash.h +++ b/include/opensrf/osrf_hash.h @@ -35,6 +35,8 @@ void* osrfHashSet( osrfHash* hash, void* item, const char* key, ... ); void* osrfHashRemove( osrfHash* hash, const char* key, ... ); +void* osrfHashExtract( osrfHash* hash, const char* key, ... ); + void* osrfHashGet( osrfHash* hash, const char* key ); void* osrfHashGetFmt( osrfHash* hash, const char* key, ... ); diff --git a/src/libopensrf/osrf_hash.c b/src/libopensrf/osrf_hash.c index feec1f8..7a4f5f7 100644 --- a/src/libopensrf/osrf_hash.c +++ b/src/libopensrf/osrf_hash.c @@ -300,11 +300,6 @@ void* osrfHashSet( osrfHash* hash, void* item, const char* key, ... ) { return NULL; } -/* Delete the entry for a specified key. If the entry exists, - and there is no callback function to destroy the associated - item, return a pointer to the formerly associated item. - Otherwise return NULL. -*/ /** @brief Remove the item for a specified key from an osrfHash. @param hash Pointer to the osrfHash from which the item is to be removed. @@ -367,6 +362,51 @@ void* osrfHashRemove( osrfHash* hash, const char* key, ... ) { return item; } +/** + @brief Extract the item for a specified key from an osrfHash. + @param hash Pointer to the osrfHash from which the item is to be extracted. + @param key A printf-style format string to be expanded into the key for the item. + Subsequent parameters, if any, will be formatted and inserted into the expanded key. + @return Pointer to the extracted item, if any (see discussion). + + osrfHashRemove removes a specified entry without destroying it, and returns a pointer + to it. If either of its first two parameters is NULL, or if no entry is present for the specified key, it returns NULL. + + This function is identical to osrfHashRemove() except that it does not destroy the + specified item. +*/ +void* osrfHashExtract( osrfHash* hash, const char* key, ... ) { + if(!(hash && key )) return NULL; + + VA_LIST_TO_STRING(key); + + osrfHashNode* node = find_item( hash, VA_BUF, NULL ); + if( !node ) return NULL; + + hash->size--; + + void* item = node->item; // to be returned + + // Mark the node as logically deleted + free(node->key); + node->key = NULL; + node->item = NULL; + + // Make the node unreachable from the rest of the linked list. + // We leave the next and prev pointers in place so that an + // iterator parked here can find its way to an adjacent node. + if( node->prev ) + node->prev->next = node->next; + else + hash->first_key = node->next; + + if( node->next ) + node->next->prev = node->prev; + else + hash->last_key = node->prev; + + return item; +} /** @brief Fetch the item stored in an osrfHash for a given key. -- 2.43.2