Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit909eebf

Browse files
committed
dshash: revise sequential scan support.
The previous coding of dshash_seq_next(), on the first call, accessedstatus->hash_table->size_log2 without holding a partition lock and withoutguaranteeing that ensure_valid_bucket_pointers() had ever been called.That oversight turns out to not have immediately visible effects, becausebucket 0 is always in partition 0, and ensure_valid_bucket_pointers() wascalled after acquiring the partition lock. However,PARTITION_FOR_BUCKET_INDEX() with a size_log2 of 0 ends up triggering formallyundefined behaviour.Simplify by accessing partition 0, without using PARTITION_FOR_BUCKET_INDEX().While at it, remove dshash_get_current(), there is no convincing usecase. Also polish a few comments.Author: Andres Freund <andres@anarazel.de>Reviewed-By: Thomas Munro <thomas.munro@gmail.com>Discussion:https://postgr.es/m/CA+hUKGL9hY_VY=+oUK+Gc1iSRx-Ls5qeYJ6q=dQVZnT3R63Taw@mail.gmail.com
1 parent55e566f commit909eebf

File tree

2 files changed

+27
-30
lines changed

2 files changed

+27
-30
lines changed

‎src/backend/lib/dshash.c

Lines changed: 27 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -601,13 +601,12 @@ dshash_memhash(const void *v, size_t size, void *arg)
601601
}
602602

603603
/*
604-
* dshash_seq_init/_next/_term
605-
* Sequentially scan through dshash table and return all the
606-
* elements one by one, return NULL when no more.
604+
* Sequentially scan through dshash table and return all the elements one by
605+
* one, return NULL when all elements have been returned.
607606
*
608-
* dshash_seq_termshould always be called when a scan finished.
609-
*The caller maydelete returned elements midst of a scan by using
610-
*dshash_delete_current(). exclusivemust betrue to delete elements.
607+
* dshash_seq_termneeds to be called when a scan finished. The caller may
608+
* delete returned elements midst of a scan by using dshash_delete_current()
609+
*if exclusive=true.
611610
*/
612611
void
613612
dshash_seq_init(dshash_seq_status*status,dshash_table*hash_table,
@@ -625,34 +624,38 @@ dshash_seq_init(dshash_seq_status *status, dshash_table *hash_table,
625624
/*
626625
* Returns the next element.
627626
*
628-
* Returned elements are locked and the callermust notexplicitlyrelease
629-
*it. It isreleasedat the next calltodshash_next().
627+
* Returned elements are locked and the callermay not release the lock. It is
628+
* releasedby future callstodshash_seq_next() or dshash_seq_term().
630629
*/
631630
void*
632631
dshash_seq_next(dshash_seq_status*status)
633632
{
634633
dsa_pointernext_item_pointer;
635634

636-
if (status->curitem==NULL)
635+
/*
636+
* Not yet holding any partition locks. Need to determine the size of the
637+
* hash table, it could have been resized since we were looking
638+
* last. Since we iterate in partition order, we can start by
639+
* unconditionally lock partition 0.
640+
*
641+
* Once we hold the lock, no resizing can happen until the scan ends. So
642+
* we don't need to repeatedly call ensure_valid_bucket_pointers().
643+
*/
644+
if (status->curpartition==-1)
637645
{
638-
intpartition;
639-
640646
Assert(status->curbucket==0);
641647
Assert(!status->hash_table->find_locked);
642648

643-
/* first shot. grab the first item. */
644-
partition=
645-
PARTITION_FOR_BUCKET_INDEX(status->curbucket,
646-
status->hash_table->size_log2);
647-
LWLockAcquire(PARTITION_LOCK(status->hash_table,partition),
649+
status->curpartition=0;
650+
651+
LWLockAcquire(PARTITION_LOCK(status->hash_table,
652+
status->curpartition),
648653
status->exclusive ?LW_EXCLUSIVE :LW_SHARED);
649-
status->curpartition=partition;
650654

651-
/* resize doesn't happen from now until seq scan ends */
652-
status->nbuckets=
653-
NUM_BUCKETS(status->hash_table->control->size_log2);
654655
ensure_valid_bucket_pointers(status->hash_table);
655656

657+
status->nbuckets=
658+
NUM_BUCKETS(status->hash_table->control->size_log2);
656659
next_item_pointer=status->hash_table->buckets[status->curbucket];
657660
}
658661
else
@@ -714,7 +717,7 @@ dshash_seq_next(dshash_seq_status *status)
714717
/*
715718
* Terminates the seqscan and release all locks.
716719
*
717-
*Shouldbealwayscalledwhen finishing or exiting a seqscan.
720+
*Needs tobe calledafter finishing or when exiting a seqscan.
718721
*/
719722
void
720723
dshash_seq_term(dshash_seq_status*status)
@@ -726,7 +729,9 @@ dshash_seq_term(dshash_seq_status *status)
726729
LWLockRelease(PARTITION_LOCK(status->hash_table,status->curpartition));
727730
}
728731

729-
/* Remove the current entry while a seq scan. */
732+
/*
733+
* Remove the current entry of the seq scan.
734+
*/
730735
void
731736
dshash_delete_current(dshash_seq_status*status)
732737
{
@@ -746,13 +751,6 @@ dshash_delete_current(dshash_seq_status *status)
746751
delete_item(hash_table,item);
747752
}
748753

749-
/* Get the current entry while a seq scan. */
750-
void*
751-
dshash_get_current(dshash_seq_status*status)
752-
{
753-
returnENTRY_FROM_ITEM(status->curitem);
754-
}
755-
756754
/*
757755
* Print debugging information about the internal state of the hash table to
758756
* stderr. The caller must hold no partition locks.

‎src/include/lib/dshash.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,6 @@ extern void dshash_seq_init(dshash_seq_status *status, dshash_table *hash_table,
101101
externvoid*dshash_seq_next(dshash_seq_status*status);
102102
externvoiddshash_seq_term(dshash_seq_status*status);
103103
externvoiddshash_delete_current(dshash_seq_status*status);
104-
externvoid*dshash_get_current(dshash_seq_status*status);
105104

106105
/* Convenience hash and compare functions wrapping memcmp and tag_hash. */
107106
externintdshash_memcmp(constvoid*a,constvoid*b,size_tsize,void*arg);

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp