mirror of
https://git.postgresql.org/git/postgresql.git
synced 2024-12-27 08:39:28 +08:00
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
This commit is contained in:
parent
bc9f1afdeb
commit
ff53d7b159
@ -110,6 +110,7 @@
|
||||
#define SH_RESET SH_MAKE_NAME(reset)
|
||||
#define SH_INSERT SH_MAKE_NAME(insert)
|
||||
#define SH_INSERT_HASH SH_MAKE_NAME(insert_hash)
|
||||
#define SH_DELETE_ITEM SH_MAKE_NAME(delete_item)
|
||||
#define SH_DELETE SH_MAKE_NAME(delete)
|
||||
#define SH_LOOKUP SH_MAKE_NAME(lookup)
|
||||
#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);
|
||||
SH_SCOPE SH_ELEMENT_TYPE *SH_LOOKUP_HASH(SH_TYPE * tb, SH_KEY_TYPE key,
|
||||
uint32 hash);
|
||||
|
||||
/* void <prefix>_delete_item(<prefix>_hash *tb, <element> *entry) */
|
||||
SH_SCOPE void SH_DELETE_ITEM(SH_TYPE * tb, SH_ELEMENT_TYPE * entry);
|
||||
|
||||
/* bool <prefix>_delete(<prefix>_hash *tb, <key> key) */
|
||||
SH_SCOPE bool SH_DELETE(SH_TYPE * tb, SH_KEY_TYPE key);
|
||||
|
||||
@ -829,7 +833,7 @@ SH_LOOKUP_HASH(SH_TYPE * tb, SH_KEY_TYPE key, uint32 hash)
|
||||
}
|
||||
|
||||
/*
|
||||
* Delete entry from hash table. Returns whether to-be-deleted key was
|
||||
* Delete entry from hash table by key. Returns whether to-be-deleted key was
|
||||
* present.
|
||||
*/
|
||||
SH_SCOPE bool
|
||||
@ -900,6 +904,61 @@ SH_DELETE(SH_TYPE * tb, SH_KEY_TYPE key)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Delete entry from hash table by entry pointer
|
||||
*/
|
||||
SH_SCOPE void
|
||||
SH_DELETE_ITEM(SH_TYPE * tb, SH_ELEMENT_TYPE * entry)
|
||||
{
|
||||
SH_ELEMENT_TYPE *lastentry = entry;
|
||||
uint32 hash = SH_ENTRY_HASH(tb, entry);
|
||||
uint32 startelem = SH_INITIAL_BUCKET(tb, hash);
|
||||
uint32 curelem;
|
||||
|
||||
/* Calculate the index of 'entry' */
|
||||
curelem = entry - &tb->data[0];
|
||||
|
||||
tb->members--;
|
||||
|
||||
/*
|
||||
* Backward shift following elements till either an empty element or an
|
||||
* element at its optimal position is encountered.
|
||||
*
|
||||
* While that sounds expensive, the average chain length is short, and
|
||||
* deletions would otherwise require tombstones.
|
||||
*/
|
||||
while (true)
|
||||
{
|
||||
SH_ELEMENT_TYPE *curentry;
|
||||
uint32 curhash;
|
||||
uint32 curoptimal;
|
||||
|
||||
curelem = SH_NEXT(tb, curelem, startelem);
|
||||
curentry = &tb->data[curelem];
|
||||
|
||||
if (curentry->status != SH_STATUS_IN_USE)
|
||||
{
|
||||
lastentry->status = SH_STATUS_EMPTY;
|
||||
break;
|
||||
}
|
||||
|
||||
curhash = SH_ENTRY_HASH(tb, curentry);
|
||||
curoptimal = SH_INITIAL_BUCKET(tb, curhash);
|
||||
|
||||
/* current is at optimal position, done */
|
||||
if (curoptimal == curelem)
|
||||
{
|
||||
lastentry->status = SH_STATUS_EMPTY;
|
||||
break;
|
||||
}
|
||||
|
||||
/* shift */
|
||||
memcpy(lastentry, curentry, sizeof(SH_ELEMENT_TYPE));
|
||||
|
||||
lastentry = curentry;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize iterator.
|
||||
*/
|
||||
@ -1102,6 +1161,7 @@ SH_STAT(SH_TYPE * tb)
|
||||
#undef SH_RESET
|
||||
#undef SH_INSERT
|
||||
#undef SH_INSERT_HASH
|
||||
#undef SH_DELETE_ITEM
|
||||
#undef SH_DELETE
|
||||
#undef SH_LOOKUP
|
||||
#undef SH_LOOKUP_HASH
|
||||
|
Loading…
Reference in New Issue
Block a user