agora inbox for [email protected]
help / color / mirror / Atom feedFrom: Kyotaro Horiguchi <[email protected]>
Subject: [PATCH 1/3] sequential scan for dshash
Date: Fri, 29 Jun 2018 16:41:04 +0900
Add sequential scan feature to dshash.
---
src/backend/lib/dshash.c | 122 +++++++++++++++++++++++++++++++++++++++++++++++
src/include/lib/dshash.h | 20 +++++++-
2 files changed, 141 insertions(+), 1 deletion(-)
diff --git a/src/backend/lib/dshash.c b/src/backend/lib/dshash.c
index b46f7c4cfd..e6c1ef44f1 100644
--- a/src/backend/lib/dshash.c
+++ b/src/backend/lib/dshash.c
@@ -592,6 +592,128 @@ dshash_memhash(const void *v, size_t size, void *arg)
return tag_hash(v, size);
}
+/*
+ * Initialize a sequential scan on the hash_table. Allows no modifications
+ * during a scan if consistent = true.
+ */
+void
+dshash_seq_init(dshash_seq_status *status, dshash_table *hash_table,
+ bool consistent)
+{
+ status->hash_table = hash_table;
+ status->curbucket = 0;
+ status->nbuckets = ((size_t) 1) << hash_table->control->size_log2;
+ status->curitem = NULL;
+ status->curpartition = -1;
+ status->consistent = consistent;
+
+ /*
+ * Protect all partitions from modification if the caller wants a
+ * consistent result.
+ */
+ if (consistent)
+ {
+ int i;
+
+ for (i = 0; i < DSHASH_NUM_PARTITIONS; ++i)
+ {
+ Assert(!LWLockHeldByMe(PARTITION_LOCK(hash_table, i)));
+
+ LWLockAcquire(PARTITION_LOCK(hash_table, i), LW_SHARED);
+ }
+ }
+ ensure_valid_bucket_pointers(hash_table);
+}
+
+void *
+dshash_seq_next(dshash_seq_status *status)
+{
+ dsa_pointer next_item_pointer;
+
+ if (status->curitem == NULL)
+ {
+ Assert (status->curbucket == 0);
+ Assert(!status->hash_table->find_locked);
+
+ /* first shot. grab the first item. */
+ next_item_pointer = status->hash_table->buckets[status->curbucket];
+ status->hash_table->find_locked = true;
+ }
+ else
+ next_item_pointer = status->curitem->next;
+
+ /* Move to the next bucket if we finished the current bucket */
+ while (!DsaPointerIsValid(next_item_pointer))
+ {
+ if (++status->curbucket >= status->nbuckets)
+ {
+ /* all buckets have been scanned. finsih. */
+ dshash_seq_release(status);
+ return NULL;
+ }
+ Assert(status->hash_table->find_locked);
+
+ next_item_pointer = status->hash_table->buckets[status->curbucket];
+
+ /*
+ * we need a lock on the scanning partition even if the caller don't
+ * requested a consistent snapshot.
+ */
+ if (!status->consistent && DsaPointerIsValid(next_item_pointer))
+ {
+ dshash_table_item *item = dsa_get_address(status->hash_table->area,
+ next_item_pointer);
+ int next_partition = PARTITION_FOR_HASH(item->hash);
+ if (status->curpartition != next_partition)
+ {
+ if (status->curpartition >= 0)
+ LWLockRelease(PARTITION_LOCK(status->hash_table,
+ status->curpartition));
+ LWLockAcquire(PARTITION_LOCK(status->hash_table,
+ next_partition),
+ LW_SHARED);
+ status->curpartition = next_partition;
+ }
+ }
+ }
+
+ status->curitem =
+ dsa_get_address(status->hash_table->area, next_item_pointer);
+ return ENTRY_FROM_ITEM(status->curitem);
+}
+
+void
+dshash_seq_release(dshash_seq_status *status)
+{
+ Assert(status->hash_table->find_locked);
+ status->hash_table->find_locked = false;
+
+ if (status->consistent)
+ {
+ int i;
+
+ for (i = 0; i < DSHASH_NUM_PARTITIONS; ++i)
+ LWLockRelease(PARTITION_LOCK(status->hash_table, i));
+ }
+ else if (status->curpartition >= 0)
+ LWLockRelease(PARTITION_LOCK(status->hash_table, status->curpartition));
+}
+
+int
+dshash_get_num_entries(dshash_table *hash_table)
+{
+ /* a shotcut implement. should be improved */
+ dshash_seq_status s;
+ void *p;
+ int n = 0;
+
+ dshash_seq_init(&s, hash_table, false);
+ while ((p = dshash_seq_next(&s)) != NULL)
+ n++;
+
+ return n;
+}
+
/*
* Print debugging information about the internal state of the hash table to
* stderr. The caller must hold no partition locks.
diff --git a/src/include/lib/dshash.h b/src/include/lib/dshash.h
index 8c733bfe25..a4565d3219 100644
--- a/src/include/lib/dshash.h
+++ b/src/include/lib/dshash.h
@@ -15,6 +15,7 @@
#define DSHASH_H
#include "utils/dsa.h"
+#include "utils/hsearch.h"
/* The opaque type representing a hash table. */
struct dshash_table;
@@ -59,6 +60,18 @@ typedef struct dshash_parameters
struct dshash_table_item;
typedef struct dshash_table_item dshash_table_item;
+struct dshash_seq_status
+{
+ dshash_table *hash_table;
+ int curbucket;
+ int nbuckets;
+ dshash_table_item *curitem;
+ int curpartition;
+ bool consistent;
+};
+
+typedef struct dshash_seq_status dshash_seq_status;
+
/* Creating, sharing and destroying from hash tables. */
extern dshash_table *dshash_create(dsa_area *area,
const dshash_parameters *params,
@@ -70,7 +83,6 @@ extern dshash_table *dshash_attach(dsa_area *area,
extern void dshash_detach(dshash_table *hash_table);
extern dshash_table_handle dshash_get_hash_table_handle(dshash_table *hash_table);
extern void dshash_destroy(dshash_table *hash_table);
-
/* Finding, creating, deleting entries. */
extern void *dshash_find(dshash_table *hash_table,
const void *key, bool exclusive);
@@ -80,6 +92,12 @@ extern bool dshash_delete_key(dshash_table *hash_table, const void *key);
extern void dshash_delete_entry(dshash_table *hash_table, void *entry);
extern void dshash_release_lock(dshash_table *hash_table, void *entry);
+/* seq scan support */
+extern void dshash_seq_init(dshash_seq_status *status, dshash_table *hash_table,
+ bool exclusive);
+extern void *dshash_seq_next(dshash_seq_status *status);
+extern void dshash_seq_release(dshash_seq_status *status);
+extern int dshash_get_num_entries(dshash_table *hash_table);
/* Convenience hash and compare functions wrapping memcmp and tag_hash. */
extern int dshash_memcmp(const void *a, const void *b, size_t size, void *arg);
extern dshash_hash dshash_memhash(const void *v, size_t size, void *arg);
--
2.16.3
----Next_Part(Tue_Jul_03_19_01_44_2018_430)--
Content-Type: Text/X-Patch; charset=us-ascii
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
filename="v2-0002-Change-stats-collector-to-an-axiliary-process.patch"
view thread (54+ messages) latest in thread
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: [PATCH 1/3] sequential scan for dshash
In-Reply-To: <no-message-id-235160@localhost>
* 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