Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit ff53d7b

Browse files
committed
Allow users of simplehash.h to perform direct deletions
Previously simplehash.h only exposed a method to perform a hash table delete using the hash table key. This meant that the delete function had to perform a hash lookup in order to find the entry to delete. Here we add a new function so that users of simplehash.h can perform a hash delete directly using the entry pointer, thus saving the hash lookup. An upcoming patch that uses simplehash.h already has performed the hash lookup so already has the entry pointer. This change will allow the code in that patch to perform the hash delete without the code in simplehash.h having to perform an additional hash lookup. Author: David Rowley Reviewed-by: Andres Freund Discussion: https://postgr.es/m/CAApHDvqFLXXge153WmPsjke5VGOSt7Ez0yD0c7eBXLfmWxs3Kw@mail.gmail.com
1 parent bc9f1af commit ff53d7b

File tree

1 file changed

+61
-1
lines changed

1 file changed

+61
-1
lines changed

src/include/lib/simplehash.h

+61-1
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,7 @@
110110
#define SH_RESET SH_MAKE_NAME(reset)
111111
#define SH_INSERT SH_MAKE_NAME(insert)
112112
#define SH_INSERT_HASH SH_MAKE_NAME(insert_hash)
113+
#define SH_DELETE_ITEM SH_MAKE_NAME(delete_item)
113114
#define SH_DELETE SH_MAKE_NAME(delete)
114115
#define SH_LOOKUP SH_MAKE_NAME(lookup)
115116
#define SH_LOOKUP_HASH SH_MAKE_NAME(lookup_hash)
@@ -217,6 +218,9 @@ SH_SCOPE SH_ELEMENT_TYPE *SH_LOOKUP(SH_TYPE * tb, SH_KEY_TYPE key);
217218
SH_SCOPE SH_ELEMENT_TYPE *SH_LOOKUP_HASH(SH_TYPE * tb, SH_KEY_TYPE key,
218219
uint32 hash);
219220

221+
/* void <prefix>_delete_item(<prefix>_hash *tb, <element> *entry) */
222+
SH_SCOPE void SH_DELETE_ITEM(SH_TYPE * tb, SH_ELEMENT_TYPE * entry);
223+
220224
/* bool <prefix>_delete(<prefix>_hash *tb, <key> key) */
221225
SH_SCOPE bool SH_DELETE(SH_TYPE * tb, SH_KEY_TYPE key);
222226

@@ -829,7 +833,7 @@ SH_LOOKUP_HASH(SH_TYPE * tb, SH_KEY_TYPE key, uint32 hash)
829833
}
830834

831835
/*
832-
* Delete entry from hash table. Returns whether to-be-deleted key was
836+
* Delete entry from hash table by key. Returns whether to-be-deleted key was
833837
* present.
834838
*/
835839
SH_SCOPE bool
@@ -900,6 +904,61 @@ SH_DELETE(SH_TYPE * tb, SH_KEY_TYPE key)
900904
}
901905
}
902906

907+
/*
908+
* Delete entry from hash table by entry pointer
909+
*/
910+
SH_SCOPE void
911+
SH_DELETE_ITEM(SH_TYPE * tb, SH_ELEMENT_TYPE * entry)
912+
{
913+
SH_ELEMENT_TYPE *lastentry = entry;
914+
uint32 hash = SH_ENTRY_HASH(tb, entry);
915+
uint32 startelem = SH_INITIAL_BUCKET(tb, hash);
916+
uint32 curelem;
917+
918+
/* Calculate the index of 'entry' */
919+
curelem = entry - &tb->data[0];
920+
921+
tb->members--;
922+
923+
/*
924+
* Backward shift following elements till either an empty element or an
925+
* element at its optimal position is encountered.
926+
*
927+
* While that sounds expensive, the average chain length is short, and
928+
* deletions would otherwise require tombstones.
929+
*/
930+
while (true)
931+
{
932+
SH_ELEMENT_TYPE *curentry;
933+
uint32 curhash;
934+
uint32 curoptimal;
935+
936+
curelem = SH_NEXT(tb, curelem, startelem);
937+
curentry = &tb->data[curelem];
938+
939+
if (curentry->status != SH_STATUS_IN_USE)
940+
{
941+
lastentry->status = SH_STATUS_EMPTY;
942+
break;
943+
}
944+
945+
curhash = SH_ENTRY_HASH(tb, curentry);
946+
curoptimal = SH_INITIAL_BUCKET(tb, curhash);
947+
948+
/* current is at optimal position, done */
949+
if (curoptimal == curelem)
950+
{
951+
lastentry->status = SH_STATUS_EMPTY;
952+
break;
953+
}
954+
955+
/* shift */
956+
memcpy(lastentry, curentry, sizeof(SH_ELEMENT_TYPE));
957+
958+
lastentry = curentry;
959+
}
960+
}
961+
903962
/*
904963
* Initialize iterator.
905964
*/
@@ -1102,6 +1161,7 @@ SH_STAT(SH_TYPE * tb)
11021161
#undef SH_RESET
11031162
#undef SH_INSERT
11041163
#undef SH_INSERT_HASH
1164+
#undef SH_DELETE_ITEM
11051165
#undef SH_DELETE
11061166
#undef SH_LOOKUP
11071167
#undef SH_LOOKUP_HASH

0 commit comments

Comments
 (0)