public inbox for [email protected]
help / color / mirror / Atom feedFrom: Jeff Davis <[email protected]>
To: [email protected]
Subject: simplehash: preserve consistency in case of OOM
Date: Fri, 17 Nov 2023 10:42:54 -0800
Message-ID: <[email protected]> (raw)
Right now, if allocation fails while growing a hashtable, it's left in
an inconsistent state and can't be used again.
Patch attached.
--
Jeff Davis
PostgreSQL Contributor Team - AWS
Attachments:
[text/x-patch] v1-0001-simplehash-preserve-consistency-in-case-of-OOM.patch (3.3K, ../[email protected]/2-v1-0001-simplehash-preserve-consistency-in-case-of-OOM.patch)
download | inline diff:
From 82068d744f668039de7249854bc42eead4e77ebc Mon Sep 17 00:00:00 2001
From: Jeff Davis <[email protected]>
Date: Fri, 17 Nov 2023 10:24:03 -0800
Subject: [PATCH v1] simplehash: preserve consistency in case of OOM.
Compute size first, then allocate, then update the structure.
Previously, an out-of-memory when growing could leave the hashtable in
an inconsistent state.
---
src/include/lib/simplehash.h | 39 ++++++++++++++++++++++++++----------
1 file changed, 28 insertions(+), 11 deletions(-)
diff --git a/src/include/lib/simplehash.h b/src/include/lib/simplehash.h
index b7adc16b80..517c81bd07 100644
--- a/src/include/lib/simplehash.h
+++ b/src/include/lib/simplehash.h
@@ -128,7 +128,8 @@
#define SH_STAT SH_MAKE_NAME(stat)
/* internal helper functions (no externally visible prototypes) */
-#define SH_COMPUTE_PARAMETERS SH_MAKE_NAME(compute_parameters)
+#define SH_COMPUTE_SIZE SH_MAKE_NAME(compute_size)
+#define SH_UPDATE_PARAMETERS SH_MAKE_NAME(update_parameters)
#define SH_NEXT SH_MAKE_NAME(next)
#define SH_PREV SH_MAKE_NAME(prev)
#define SH_DISTANCE_FROM_OPTIMAL SH_MAKE_NAME(distance)
@@ -303,11 +304,11 @@ SH_SCOPE void SH_STAT(SH_TYPE * tb);
#endif
/*
- * Compute sizing parameters for hashtable. Called when creating and growing
- * the hashtable.
+ * Compute allocation size for hashtable. Result can be passed to
+ * SH_UPDATE_PARAMETERS.
*/
-static inline void
-SH_COMPUTE_PARAMETERS(SH_TYPE * tb, uint64 newsize)
+static inline uint64
+SH_COMPUTE_SIZE(uint64 newsize)
{
uint64 size;
@@ -325,6 +326,18 @@ SH_COMPUTE_PARAMETERS(SH_TYPE * tb, uint64 newsize)
if (unlikely((((uint64) sizeof(SH_ELEMENT_TYPE)) * size) >= SIZE_MAX / 2))
sh_error("hash table too large");
+ return size;
+}
+
+/*
+ * Update sizing parameters for hashtable. Called when creating and growing
+ * the hashtable.
+ */
+static inline void
+SH_UPDATE_PARAMETERS(SH_TYPE * tb, uint64 newsize)
+{
+ uint64 size = SH_COMPUTE_SIZE(newsize);
+
/* now set size */
tb->size = size;
tb->sizemask = (uint32) (size - 1);
@@ -446,10 +459,11 @@ SH_CREATE(MemoryContext ctx, uint32 nelements, void *private_data)
/* increase nelements by fillfactor, want to store nelements elements */
size = Min((double) SH_MAX_SIZE, ((double) nelements) / SH_FILLFACTOR);
- SH_COMPUTE_PARAMETERS(tb, size);
+ size = SH_COMPUTE_SIZE(size);
- tb->data = (SH_ELEMENT_TYPE *) SH_ALLOCATE(tb, sizeof(SH_ELEMENT_TYPE) * tb->size);
+ tb->data = (SH_ELEMENT_TYPE *) SH_ALLOCATE(tb, sizeof(SH_ELEMENT_TYPE) * size);
+ SH_UPDATE_PARAMETERS(tb, size);
return tb;
}
@@ -490,10 +504,12 @@ SH_GROW(SH_TYPE * tb, uint64 newsize)
Assert(oldsize != SH_MAX_SIZE);
Assert(oldsize < newsize);
- /* compute parameters for new table */
- SH_COMPUTE_PARAMETERS(tb, newsize);
+ newsize = SH_COMPUTE_SIZE(newsize);
+
+ tb->data = (SH_ELEMENT_TYPE *) SH_ALLOCATE(tb, sizeof(SH_ELEMENT_TYPE) * newsize);
- tb->data = (SH_ELEMENT_TYPE *) SH_ALLOCATE(tb, sizeof(SH_ELEMENT_TYPE) * tb->size);
+ /* compute parameters for new table */
+ SH_UPDATE_PARAMETERS(tb, newsize);
newdata = tb->data;
@@ -1173,7 +1189,8 @@ SH_STAT(SH_TYPE * tb)
#undef SH_STAT
/* internal function names */
-#undef SH_COMPUTE_PARAMETERS
+#undef SH_COMPUTE_SIZE
+#undef SH_UPDATE_PARAMETERS
#undef SH_COMPARE_KEYS
#undef SH_INITIAL_BUCKET
#undef SH_NEXT
--
2.34.1
view thread (2+ messages)
reply
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Reply to all the recipients using the --to and --cc options:
reply via email
To: [email protected]
Cc: [email protected]
Subject: Re: simplehash: preserve consistency in case of OOM
In-Reply-To: <[email protected]>
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
This inbox is served by agora; see mirroring instructions
for how to clone and mirror all data and code used for this inbox