PostgreSQL Source Code  git master
hashutil.c File Reference
#include "postgres.h"
#include "access/hash.h"
#include "access/reloptions.h"
#include "access/relscan.h"
#include "port/pg_bitutils.h"
#include "storage/buf_internals.h"
#include "utils/lsyscache.h"
#include "utils/rel.h"
Include dependency graph for hashutil.c:

Go to the source code of this file.

Macros

#define CALC_NEW_BUCKET(old_bucket, lowmask)   old_bucket | (lowmask + 1)
 

Functions

bool _hash_checkqual (IndexScanDesc scan, IndexTuple itup)
 
uint32 _hash_datum2hashkey (Relation rel, Datum key)
 
uint32 _hash_datum2hashkey_type (Relation rel, Datum key, Oid keytype)
 
Bucket _hash_hashkey2bucket (uint32 hashkey, uint32 maxbucket, uint32 highmask, uint32 lowmask)
 
uint32 _hash_spareindex (uint32 num_bucket)
 
uint32 _hash_get_totalbuckets (uint32 splitpoint_phase)
 
void _hash_checkpage (Relation rel, Buffer buf, int flags)
 
byteahashoptions (Datum reloptions, bool validate)
 
uint32 _hash_get_indextuple_hashkey (IndexTuple itup)
 
bool _hash_convert_tuple (Relation index, Datum *user_values, bool *user_isnull, Datum *index_values, bool *index_isnull)
 
OffsetNumber _hash_binsearch (Page page, uint32 hash_value)
 
OffsetNumber _hash_binsearch_last (Page page, uint32 hash_value)
 
BlockNumber _hash_get_oldblock_from_newbucket (Relation rel, Bucket new_bucket)
 
BlockNumber _hash_get_newblock_from_oldbucket (Relation rel, Bucket old_bucket)
 
Bucket _hash_get_newbucket_from_oldbucket (Relation rel, Bucket old_bucket, uint32 lowmask, uint32 maxbucket)
 
void _hash_kill_items (IndexScanDesc scan)
 

Macro Definition Documentation

◆ CALC_NEW_BUCKET

#define CALC_NEW_BUCKET (   old_bucket,
  lowmask 
)    old_bucket | (lowmask + 1)

Definition at line 25 of file hashutil.c.

Referenced by _hash_get_newbucket_from_oldbucket().

Function Documentation

◆ _hash_binsearch()

OffsetNumber _hash_binsearch ( Page  page,
uint32  hash_value 
)

Definition at line 351 of file hashutil.c.

References _hash_get_indextuple_hashkey(), Assert, FirstOffsetNumber, lower(), OffsetNumberIsValid, PageGetItem, PageGetItemId, PageGetMaxOffsetNumber, and upper().

Referenced by _hash_pgaddmultitup(), _hash_pgaddtup(), and _hash_readpage().

352 {
355 
356  /* Loop invariant: lower <= desired place <= upper */
357  upper = PageGetMaxOffsetNumber(page) + 1;
358  lower = FirstOffsetNumber;
359 
360  while (upper > lower)
361  {
362  OffsetNumber off;
363  IndexTuple itup;
364  uint32 hashkey;
365 
366  off = (upper + lower) / 2;
368 
369  itup = (IndexTuple) PageGetItem(page, PageGetItemId(page, off));
370  hashkey = _hash_get_indextuple_hashkey(itup);
371  if (hashkey < hash_value)
372  lower = off + 1;
373  else
374  upper = off;
375  }
376 
377  return lower;
378 }
Datum lower(PG_FUNCTION_ARGS)
Definition: oracle_compat.c:44
Datum upper(PG_FUNCTION_ARGS)
Definition: oracle_compat.c:75
#define PageGetMaxOffsetNumber(page)
Definition: bufpage.h:357
uint16 OffsetNumber
Definition: off.h:24
uint32 _hash_get_indextuple_hashkey(IndexTuple itup)
Definition: hashutil.c:292
#define FirstOffsetNumber
Definition: off.h:27
IndexTupleData * IndexTuple
Definition: itup.h:53
unsigned int uint32
Definition: c.h:374
#define PageGetItemId(page, offsetNumber)
Definition: bufpage.h:235
#define Assert(condition)
Definition: c.h:745
#define OffsetNumberIsValid(offsetNumber)
Definition: off.h:39
#define PageGetItem(page, itemId)
Definition: bufpage.h:340

◆ _hash_binsearch_last()

OffsetNumber _hash_binsearch_last ( Page  page,
uint32  hash_value 
)

Definition at line 389 of file hashutil.c.

References _hash_get_indextuple_hashkey(), Assert, FirstOffsetNumber, lower(), OffsetNumberIsValid, PageGetItem, PageGetItemId, PageGetMaxOffsetNumber, and upper().

Referenced by _hash_readpage().

390 {
393 
394  /* Loop invariant: lower <= desired place <= upper */
395  upper = PageGetMaxOffsetNumber(page);
396  lower = FirstOffsetNumber - 1;
397 
398  while (upper > lower)
399  {
400  IndexTuple itup;
401  OffsetNumber off;
402  uint32 hashkey;
403 
404  off = (upper + lower + 1) / 2;
406 
407  itup = (IndexTuple) PageGetItem(page, PageGetItemId(page, off));
408  hashkey = _hash_get_indextuple_hashkey(itup);
409  if (hashkey > hash_value)
410  upper = off - 1;
411  else
412  lower = off;
413  }
414 
415  return lower;
416 }
Datum lower(PG_FUNCTION_ARGS)
Definition: oracle_compat.c:44
Datum upper(PG_FUNCTION_ARGS)
Definition: oracle_compat.c:75
#define PageGetMaxOffsetNumber(page)
Definition: bufpage.h:357
uint16 OffsetNumber
Definition: off.h:24
uint32 _hash_get_indextuple_hashkey(IndexTuple itup)
Definition: hashutil.c:292
#define FirstOffsetNumber
Definition: off.h:27
IndexTupleData * IndexTuple
Definition: itup.h:53
unsigned int uint32
Definition: c.h:374
#define PageGetItemId(page, offsetNumber)
Definition: bufpage.h:235
#define Assert(condition)
Definition: c.h:745
#define OffsetNumberIsValid(offsetNumber)
Definition: off.h:39
#define PageGetItem(page, itemId)
Definition: bufpage.h:340

◆ _hash_checkpage()

void _hash_checkpage ( Relation  rel,
Buffer  buf,
int  flags 
)

Definition at line 211 of file hashutil.c.

References BufferGetBlockNumber(), BufferGetPage, ereport, errcode(), errhint(), errmsg(), ERROR, HASH_MAGIC, HASH_VERSION, HashMetaPageData::hashm_magic, HashMetaPageData::hashm_version, HashPageOpaqueData::hasho_flag, HashPageGetMeta, LH_META_PAGE, MAXALIGN, PageGetSpecialPointer, PageGetSpecialSize, PageIsNew, and RelationGetRelationName.

Referenced by _hash_addovflpage(), _hash_expandtable(), _hash_freeovflpage(), _hash_getbuf(), _hash_getbuf_with_condlock_cleanup(), _hash_getbuf_with_strategy(), _hash_pgaddmultitup(), _hash_pgaddtup(), _hash_readpage(), and hashbulkdelete().

212 {
213  Page page = BufferGetPage(buf);
214 
215  /*
216  * ReadBuffer verifies that every newly-read page passes
217  * PageHeaderIsValid, which means it either contains a reasonably sane
218  * page header or is all-zero. We have to defend against the all-zero
219  * case, however.
220  */
221  if (PageIsNew(page))
222  ereport(ERROR,
223  (errcode(ERRCODE_INDEX_CORRUPTED),
224  errmsg("index \"%s\" contains unexpected zero page at block %u",
227  errhint("Please REINDEX it.")));
228 
229  /*
230  * Additionally check that the special area looks sane.
231  */
232  if (PageGetSpecialSize(page) != MAXALIGN(sizeof(HashPageOpaqueData)))
233  ereport(ERROR,
234  (errcode(ERRCODE_INDEX_CORRUPTED),
235  errmsg("index \"%s\" contains corrupted page at block %u",
238  errhint("Please REINDEX it.")));
239 
240  if (flags)
241  {
243 
244  if ((opaque->hasho_flag & flags) == 0)
245  ereport(ERROR,
246  (errcode(ERRCODE_INDEX_CORRUPTED),
247  errmsg("index \"%s\" contains corrupted page at block %u",
250  errhint("Please REINDEX it.")));
251  }
252 
253  /*
254  * When checking the metapage, also verify magic number and version.
255  */
256  if (flags == LH_META_PAGE)
257  {
258  HashMetaPage metap = HashPageGetMeta(page);
259 
260  if (metap->hashm_magic != HASH_MAGIC)
261  ereport(ERROR,
262  (errcode(ERRCODE_INDEX_CORRUPTED),
263  errmsg("index \"%s\" is not a hash index",
264  RelationGetRelationName(rel))));
265 
266  if (metap->hashm_version != HASH_VERSION)
267  ereport(ERROR,
268  (errcode(ERRCODE_INDEX_CORRUPTED),
269  errmsg("index \"%s\" has wrong hash version",
271  errhint("Please REINDEX it.")));
272  }
273 }
int errhint(const char *fmt,...)
Definition: elog.c:1071
#define LH_META_PAGE
Definition: hash.h:57
uint32 hashm_magic
Definition: hash.h:244
int errcode(int sqlerrcode)
Definition: elog.c:610
#define HASH_VERSION
Definition: hash.h:199
#define HASH_MAGIC
Definition: hash.h:198
#define ERROR
Definition: elog.h:43
uint32 hashm_version
Definition: hash.h:245
static char * buf
Definition: pg_test_fsync.c:67
#define RelationGetRelationName(relation)
Definition: rel.h:490
#define BufferGetPage(buffer)
Definition: bufmgr.h:169
#define ereport(elevel,...)
Definition: elog.h:144
#define PageGetSpecialPointer(page)
Definition: bufpage.h:326
HashPageOpaqueData * HashPageOpaque
Definition: hash.h:86
#define MAXALIGN(LEN)
Definition: c.h:698
#define PageGetSpecialSize(page)
Definition: bufpage.h:300
uint16 hasho_flag
Definition: hash.h:82
BlockNumber BufferGetBlockNumber(Buffer buffer)
Definition: bufmgr.c:2668
#define PageIsNew(page)
Definition: bufpage.h:229
#define HashPageGetMeta(page)
Definition: hash.h:321
int errmsg(const char *fmt,...)
Definition: elog.c:824
Pointer Page
Definition: bufpage.h:78

◆ _hash_checkqual()

bool _hash_checkqual ( IndexScanDesc  scan,
IndexTuple  itup 
)

Definition at line 32 of file hashutil.c.

References DatumGetBool, FunctionCall2Coll(), index_getattr, IndexScanDescData::indexRelation, sort-test::key, IndexScanDescData::keyData, IndexScanDescData::numberOfKeys, RelationGetDescr, ScanKeyData::sk_argument, ScanKeyData::sk_attno, ScanKeyData::sk_collation, ScanKeyData::sk_flags, ScanKeyData::sk_func, SK_ISNULL, and test().

Referenced by _hash_load_qualified_items().

33 {
34  /*
35  * Currently, we can't check any of the scan conditions since we do not
36  * have the original index entry value to supply to the sk_func. Always
37  * return true; we expect that hashgettuple already set the recheck flag
38  * to make the main indexscan code do it.
39  */
40 #ifdef NOT_USED
41  TupleDesc tupdesc = RelationGetDescr(scan->indexRelation);
42  ScanKey key = scan->keyData;
43  int scanKeySize = scan->numberOfKeys;
44 
45  while (scanKeySize > 0)
46  {
47  Datum datum;
48  bool isNull;
49  Datum test;
50 
51  datum = index_getattr(itup,
52  key->sk_attno,
53  tupdesc,
54  &isNull);
55 
56  /* assume sk_func is strict */
57  if (isNull)
58  return false;
59  if (key->sk_flags & SK_ISNULL)
60  return false;
61 
62  test = FunctionCall2Coll(&key->sk_func, key->sk_collation,
63  datum, key->sk_argument);
64 
65  if (!DatumGetBool(test))
66  return false;
67 
68  key++;
69  scanKeySize--;
70  }
71 #endif
72 
73  return true;
74 }
static void test(void)
#define RelationGetDescr(relation)
Definition: rel.h:482
Datum FunctionCall2Coll(FmgrInfo *flinfo, Oid collation, Datum arg1, Datum arg2)
Definition: fmgr.c:1152
Relation indexRelation
Definition: relscan.h:115
FmgrInfo sk_func
Definition: skey.h:71
#define DatumGetBool(X)
Definition: postgres.h:393
#define SK_ISNULL
Definition: skey.h:115
uintptr_t Datum
Definition: postgres.h:367
int sk_flags
Definition: skey.h:66
#define index_getattr(tup, attnum, tupleDesc, isnull)
Definition: itup.h:100
struct ScanKeyData * keyData
Definition: relscan.h:119
Oid sk_collation
Definition: skey.h:70
Datum sk_argument
Definition: skey.h:72
AttrNumber sk_attno
Definition: skey.h:67

◆ _hash_convert_tuple()

bool _hash_convert_tuple ( Relation  index,
Datum user_values,
bool user_isnull,
Datum index_values,
bool index_isnull 
)

Definition at line 319 of file hashutil.c.

References _hash_datum2hashkey(), and UInt32GetDatum.

Referenced by hashbuildCallback(), and hashinsert().

322 {
323  uint32 hashkey;
324 
325  /*
326  * We do not insert null values into hash indexes. This is okay because
327  * the only supported search operator is '=', and we assume it is strict.
328  */
329  if (user_isnull[0])
330  return false;
331 
332  hashkey = _hash_datum2hashkey(index, user_values[0]);
333  index_values[0] = UInt32GetDatum(hashkey);
334  index_isnull[0] = false;
335  return true;
336 }
uint32 _hash_datum2hashkey(Relation rel, Datum key)
Definition: hashutil.c:83
unsigned int uint32
Definition: c.h:374
#define UInt32GetDatum(X)
Definition: postgres.h:493

◆ _hash_datum2hashkey()

uint32 _hash_datum2hashkey ( Relation  rel,
Datum  key 
)

Definition at line 83 of file hashutil.c.

References DatumGetUInt32, FunctionCall1Coll(), HASHSTANDARD_PROC, index_getprocinfo(), and RelationData::rd_indcollation.

Referenced by _hash_convert_tuple(), and _hash_first().

84 {
85  FmgrInfo *procinfo;
86  Oid collation;
87 
88  /* XXX assumes index has only one attribute */
89  procinfo = index_getprocinfo(rel, 1, HASHSTANDARD_PROC);
90  collation = rel->rd_indcollation[0];
91 
92  return DatumGetUInt32(FunctionCall1Coll(procinfo, collation, key));
93 }
#define DatumGetUInt32(X)
Definition: postgres.h:486
Definition: fmgr.h:56
FmgrInfo * index_getprocinfo(Relation irel, AttrNumber attnum, uint16 procnum)
Definition: indexam.c:800
unsigned int Oid
Definition: postgres_ext.h:31
Oid * rd_indcollation
Definition: rel.h:199
#define HASHSTANDARD_PROC
Definition: hash.h:353
Datum FunctionCall1Coll(FmgrInfo *flinfo, Oid collation, Datum arg1)
Definition: fmgr.c:1132

◆ _hash_datum2hashkey_type()

uint32 _hash_datum2hashkey_type ( Relation  rel,
Datum  key,
Oid  keytype 
)

Definition at line 103 of file hashutil.c.

References DatumGetUInt32, elog, ERROR, get_opfamily_proc(), HASHSTANDARD_PROC, OidFunctionCall1Coll(), RelationData::rd_indcollation, RelationData::rd_opfamily, RegProcedureIsValid, and RelationGetRelationName.

Referenced by _hash_first().

104 {
105  RegProcedure hash_proc;
106  Oid collation;
107 
108  /* XXX assumes index has only one attribute */
109  hash_proc = get_opfamily_proc(rel->rd_opfamily[0],
110  keytype,
111  keytype,
113  if (!RegProcedureIsValid(hash_proc))
114  elog(ERROR, "missing support function %d(%u,%u) for index \"%s\"",
115  HASHSTANDARD_PROC, keytype, keytype,
117  collation = rel->rd_indcollation[0];
118 
119  return DatumGetUInt32(OidFunctionCall1Coll(hash_proc, collation, key));
120 }
#define DatumGetUInt32(X)
Definition: postgres.h:486
regproc RegProcedure
Definition: c.h:518
unsigned int Oid
Definition: postgres_ext.h:31
Oid * rd_indcollation
Definition: rel.h:199
#define ERROR
Definition: elog.h:43
#define RegProcedureIsValid(p)
Definition: c.h:653
#define RelationGetRelationName(relation)
Definition: rel.h:490
Oid * rd_opfamily
Definition: rel.h:189
#define HASHSTANDARD_PROC
Definition: hash.h:353
Datum OidFunctionCall1Coll(Oid functionId, Oid collation, Datum arg1)
Definition: fmgr.c:1414
Oid get_opfamily_proc(Oid opfamily, Oid lefttype, Oid righttype, int16 procnum)
Definition: lsyscache.c:794
#define elog(elevel,...)
Definition: elog.h:214

◆ _hash_get_indextuple_hashkey()

uint32 _hash_get_indextuple_hashkey ( IndexTuple  itup)

Definition at line 292 of file hashutil.c.

References IndexInfoFindDataOffset, and IndexTupleData::t_info.

Referenced by _h_indexbuild(), _hash_binsearch(), _hash_binsearch_last(), _hash_doinsert(), _hash_load_qualified_items(), _hash_pgaddmultitup(), _hash_pgaddtup(), _hash_splitbucket(), hash_page_items(), and hashbucketcleanup().

293 {
294  char *attp;
295 
296  /*
297  * We assume the hash key is the first attribute and can't be null, so
298  * this can be done crudely but very very cheaply ...
299  */
300  attp = (char *) itup + IndexInfoFindDataOffset(itup->t_info);
301  return *((uint32 *) attp);
302 }
#define IndexInfoFindDataOffset(t_info)
Definition: itup.h:80
unsigned int uint32
Definition: c.h:374
unsigned short t_info
Definition: itup.h:49

◆ _hash_get_newblock_from_oldbucket()

BlockNumber _hash_get_newblock_from_oldbucket ( Relation  rel,
Bucket  old_bucket 
)

Definition at line 462 of file hashutil.c.

References _hash_get_newbucket_from_oldbucket(), _hash_getbuf(), _hash_relbuf(), BUCKET_TO_BLKNO, BufferGetPage, HASH_METAPAGE, HASH_READ, HashMetaPageData::hashm_lowmask, HashMetaPageData::hashm_maxbucket, HashPageGetMeta, and LH_META_PAGE.

Referenced by _hash_finish_split().

463 {
464  Bucket new_bucket;
465  Buffer metabuf;
466  HashMetaPage metap;
467  BlockNumber blkno;
468 
470  metap = HashPageGetMeta(BufferGetPage(metabuf));
471 
472  new_bucket = _hash_get_newbucket_from_oldbucket(rel, old_bucket,
473  metap->hashm_lowmask,
474  metap->hashm_maxbucket);
475  blkno = BUCKET_TO_BLKNO(metap, new_bucket);
476 
477  _hash_relbuf(rel, metabuf);
478 
479  return blkno;
480 }
#define LH_META_PAGE
Definition: hash.h:57
uint32 BlockNumber
Definition: block.h:31
Buffer _hash_getbuf(Relation rel, BlockNumber blkno, int access, int flags)
Definition: hashpage.c:69
uint32 hashm_lowmask
Definition: hash.h:254
#define BUCKET_TO_BLKNO(metap, B)
Definition: hash.h:39
#define HASH_READ
Definition: hash.h:337
uint32 Bucket
Definition: hash.h:35
Bucket _hash_get_newbucket_from_oldbucket(Relation rel, Bucket old_bucket, uint32 lowmask, uint32 maxbucket)
Definition: hashutil.c:495
#define BufferGetPage(buffer)
Definition: bufmgr.h:169
#define HASH_METAPAGE
Definition: hash.h:196
void _hash_relbuf(Relation rel, Buffer buf)
Definition: hashpage.c:265
uint32 hashm_maxbucket
Definition: hash.h:252
#define HashPageGetMeta(page)
Definition: hash.h:321
int Buffer
Definition: buf.h:23

◆ _hash_get_newbucket_from_oldbucket()

Bucket _hash_get_newbucket_from_oldbucket ( Relation  rel,
Bucket  old_bucket,
uint32  lowmask,
uint32  maxbucket 
)

Definition at line 495 of file hashutil.c.

References CALC_NEW_BUCKET.

Referenced by _hash_get_newblock_from_oldbucket(), and hashbucketcleanup().

497 {
498  Bucket new_bucket;
499 
500  new_bucket = CALC_NEW_BUCKET(old_bucket, lowmask);
501  if (new_bucket > maxbucket)
502  {
503  lowmask = lowmask >> 1;
504  new_bucket = CALC_NEW_BUCKET(old_bucket, lowmask);
505  }
506 
507  return new_bucket;
508 }
#define CALC_NEW_BUCKET(old_bucket, lowmask)
Definition: hashutil.c:25
uint32 Bucket
Definition: hash.h:35

◆ _hash_get_oldblock_from_newbucket()

BlockNumber _hash_get_oldblock_from_newbucket ( Relation  rel,
Bucket  new_bucket 
)

Definition at line 423 of file hashutil.c.

References _hash_getbuf(), _hash_relbuf(), BUCKET_TO_BLKNO, BufferGetPage, fls(), HASH_METAPAGE, HASH_READ, HashPageGetMeta, and LH_META_PAGE.

Referenced by _hash_first().

424 {
425  Bucket old_bucket;
426  uint32 mask;
427  Buffer metabuf;
428  HashMetaPage metap;
429  BlockNumber blkno;
430 
431  /*
432  * To get the old bucket from the current bucket, we need a mask to modulo
433  * into lower half of table. This mask is stored in meta page as
434  * hashm_lowmask, but here we can't rely on the same, because we need a
435  * value of lowmask that was prevalent at the time when bucket split was
436  * started. Masking the most significant bit of new bucket would give us
437  * old bucket.
438  */
439  mask = (((uint32) 1) << (fls(new_bucket) - 1)) - 1;
440  old_bucket = new_bucket & mask;
441 
443  metap = HashPageGetMeta(BufferGetPage(metabuf));
444 
445  blkno = BUCKET_TO_BLKNO(metap, old_bucket);
446 
447  _hash_relbuf(rel, metabuf);
448 
449  return blkno;
450 }
#define LH_META_PAGE
Definition: hash.h:57
uint32 BlockNumber
Definition: block.h:31
Buffer _hash_getbuf(Relation rel, BlockNumber blkno, int access, int flags)
Definition: hashpage.c:69
#define BUCKET_TO_BLKNO(metap, B)
Definition: hash.h:39
int fls(int mask)
Definition: fls.c:55
#define HASH_READ
Definition: hash.h:337
uint32 Bucket
Definition: hash.h:35
unsigned int uint32
Definition: c.h:374
#define BufferGetPage(buffer)
Definition: bufmgr.h:169
#define HASH_METAPAGE
Definition: hash.h:196
void _hash_relbuf(Relation rel, Buffer buf)
Definition: hashpage.c:265
#define HashPageGetMeta(page)
Definition: hash.h:321
int Buffer
Definition: buf.h:23

◆ _hash_get_totalbuckets()

uint32 _hash_get_totalbuckets ( uint32  splitpoint_phase)

Definition at line 175 of file hashutil.c.

References HASH_SPLITPOINT_GROUPS_WITH_ONE_PHASE, HASH_SPLITPOINT_PHASE_BITS, and HASH_SPLITPOINT_PHASE_MASK.

Referenced by _hash_expandtable(), _hash_init_metabuffer(), _hash_ovflblkno_to_bitno(), and bitno_to_blkno().

176 {
177  uint32 splitpoint_group;
178  uint32 total_buckets;
179  uint32 phases_within_splitpoint_group;
180 
181  if (splitpoint_phase < HASH_SPLITPOINT_GROUPS_WITH_ONE_PHASE)
182  return (1 << splitpoint_phase);
183 
184  /* get splitpoint's group */
185  splitpoint_group = HASH_SPLITPOINT_GROUPS_WITH_ONE_PHASE;
186  splitpoint_group +=
187  ((splitpoint_phase - HASH_SPLITPOINT_GROUPS_WITH_ONE_PHASE) >>
189 
190  /* account for buckets before splitpoint_group */
191  total_buckets = (1 << (splitpoint_group - 1));
192 
193  /* account for buckets within splitpoint_group */
194  phases_within_splitpoint_group =
195  (((splitpoint_phase - HASH_SPLITPOINT_GROUPS_WITH_ONE_PHASE) &
196  HASH_SPLITPOINT_PHASE_MASK) + 1); /* from 0-based to 1-based */
197  total_buckets +=
198  (((1 << (splitpoint_group - 1)) >> HASH_SPLITPOINT_PHASE_BITS) *
199  phases_within_splitpoint_group);
200 
201  return total_buckets;
202 }
#define HASH_SPLITPOINT_PHASE_MASK
Definition: hash.h:232
#define HASH_SPLITPOINT_PHASE_BITS
Definition: hash.h:230
unsigned int uint32
Definition: c.h:374
#define HASH_SPLITPOINT_GROUPS_WITH_ONE_PHASE
Definition: hash.h:233

◆ _hash_hashkey2bucket()

Bucket _hash_hashkey2bucket ( uint32  hashkey,
uint32  maxbucket,
uint32  highmask,
uint32  lowmask 
)

Definition at line 126 of file hashutil.c.

Referenced by _h_indexbuild(), _hash_getbucketbuf_from_hashkey(), _hash_splitbucket(), comparetup_index_hash(), and hashbucketcleanup().

128 {
129  Bucket bucket;
130 
131  bucket = hashkey & highmask;
132  if (bucket > maxbucket)
133  bucket = bucket & lowmask;
134 
135  return bucket;
136 }
uint32 Bucket
Definition: hash.h:35

◆ _hash_kill_items()

void _hash_kill_items ( IndexScanDesc  scan)

Definition at line 537 of file hashutil.c.

References _hash_getbuf(), _hash_relbuf(), Assert, buf, HashScanPosData::buf, BUFFER_LOCK_SHARE, BUFFER_LOCK_UNLOCK, BufferGetPage, HashScanPosData::currPage, HashScanOpaqueData::currPos, HashScanPosData::firstItem, HASH_READ, HashScanPosIsPinned, HashScanPosIsValid, HashScanOpaqueData::hashso_bucket_buf, HashScanPosItem::heapTid, i, HashScanPosItem::indexOffset, IndexScanDescData::indexRelation, ItemIdMarkDead, ItemPointerEquals(), HashScanPosData::items, HashScanOpaqueData::killedItems, LH_OVERFLOW_PAGE, LH_PAGE_HAS_DEAD_TUPLES, LockBuffer(), MarkBufferDirtyHint(), HashScanOpaqueData::numKilled, OffsetNumberNext, IndexScanDescData::opaque, PageGetItem, PageGetItemId, PageGetMaxOffsetNumber, PageGetSpecialPointer, and IndexTupleData::t_tid.

Referenced by _hash_next(), _hash_readpage(), hashendscan(), and hashrescan().

538 {
539  HashScanOpaque so = (HashScanOpaque) scan->opaque;
540  Relation rel = scan->indexRelation;
541  BlockNumber blkno;
542  Buffer buf;
543  Page page;
544  HashPageOpaque opaque;
545  OffsetNumber offnum,
546  maxoff;
547  int numKilled = so->numKilled;
548  int i;
549  bool killedsomething = false;
550  bool havePin = false;
551 
552  Assert(so->numKilled > 0);
553  Assert(so->killedItems != NULL);
555 
556  /*
557  * Always reset the scan state, so we don't look for same items on other
558  * pages.
559  */
560  so->numKilled = 0;
561 
562  blkno = so->currPos.currPage;
563  if (HashScanPosIsPinned(so->currPos))
564  {
565  /*
566  * We already have pin on this buffer, so, all we need to do is
567  * acquire lock on it.
568  */
569  havePin = true;
570  buf = so->currPos.buf;
572  }
573  else
574  buf = _hash_getbuf(rel, blkno, HASH_READ, LH_OVERFLOW_PAGE);
575 
576  page = BufferGetPage(buf);
577  opaque = (HashPageOpaque) PageGetSpecialPointer(page);
578  maxoff = PageGetMaxOffsetNumber(page);
579 
580  for (i = 0; i < numKilled; i++)
581  {
582  int itemIndex = so->killedItems[i];
583  HashScanPosItem *currItem = &so->currPos.items[itemIndex];
584 
585  offnum = currItem->indexOffset;
586 
587  Assert(itemIndex >= so->currPos.firstItem &&
588  itemIndex <= so->currPos.lastItem);
589 
590  while (offnum <= maxoff)
591  {
592  ItemId iid = PageGetItemId(page, offnum);
593  IndexTuple ituple = (IndexTuple) PageGetItem(page, iid);
594 
595  if (ItemPointerEquals(&ituple->t_tid, &currItem->heapTid))
596  {
597  /* found the item */
598  ItemIdMarkDead(iid);
599  killedsomething = true;
600  break; /* out of inner search loop */
601  }
602  offnum = OffsetNumberNext(offnum);
603  }
604  }
605 
606  /*
607  * Since this can be redone later if needed, mark as dirty hint. Whenever
608  * we mark anything LP_DEAD, we also set the page's
609  * LH_PAGE_HAS_DEAD_TUPLES flag, which is likewise just a hint.
610  */
611  if (killedsomething)
612  {
613  opaque->hasho_flag |= LH_PAGE_HAS_DEAD_TUPLES;
614  MarkBufferDirtyHint(buf, true);
615  }
616 
617  if (so->hashso_bucket_buf == so->currPos.buf ||
618  havePin)
620  else
621  _hash_relbuf(rel, buf);
622 }
HashScanOpaqueData * HashScanOpaque
Definition: hash.h:190
#define BUFFER_LOCK_UNLOCK
Definition: bufmgr.h:96
void MarkBufferDirtyHint(Buffer buffer, bool buffer_std)
Definition: bufmgr.c:3588
#define ItemIdMarkDead(itemId)
Definition: itemid.h:179
#define HashScanPosIsPinned(scanpos)
Definition: hash.h:128
#define HashScanPosIsValid(scanpos)
Definition: hash.h:135
ItemPointerData t_tid
Definition: itup.h:37
uint32 BlockNumber
Definition: block.h:31
Buffer _hash_getbuf(Relation rel, BlockNumber blkno, int access, int flags)
Definition: hashpage.c:69
#define PageGetMaxOffsetNumber(page)
Definition: bufpage.h:357
Relation indexRelation
Definition: relscan.h:115
uint16 OffsetNumber
Definition: off.h:24
#define HASH_READ
Definition: hash.h:337
int * killedItems
Definition: hash.h:180
static char * buf
Definition: pg_test_fsync.c:67
IndexTupleData * IndexTuple
Definition: itup.h:53
BlockNumber currPage
Definition: hash.h:110
#define BufferGetPage(buffer)
Definition: bufmgr.h:169
Buffer hashso_bucket_buf
Definition: hash.h:162
#define PageGetItemId(page, offsetNumber)
Definition: bufpage.h:235
Buffer buf
Definition: hash.h:109
#define LH_OVERFLOW_PAGE
Definition: hash.h:54
void LockBuffer(Buffer buffer, int mode)
Definition: bufmgr.c:3757
void _hash_relbuf(Relation rel, Buffer buf)
Definition: hashpage.c:265
#define Assert(condition)
Definition: c.h:745
#define OffsetNumberNext(offsetNumber)
Definition: off.h:52
#define PageGetSpecialPointer(page)
Definition: bufpage.h:326
HashPageOpaqueData * HashPageOpaque
Definition: hash.h:86
bool ItemPointerEquals(ItemPointer pointer1, ItemPointer pointer2)
Definition: itemptr.c:29
HashScanPosData currPos
Definition: hash.h:187
OffsetNumber indexOffset
Definition: hash.h:104
int i
#define BUFFER_LOCK_SHARE
Definition: bufmgr.h:97
ItemPointerData heapTid
Definition: hash.h:103
int firstItem
Definition: hash.h:121
int Buffer
Definition: buf.h:23
#define LH_PAGE_HAS_DEAD_TUPLES
Definition: hash.h:61
#define PageGetItem(page, itemId)
Definition: bufpage.h:340
Pointer Page
Definition: bufpage.h:78
HashScanPosItem items[MaxIndexTuplesPerPage]
Definition: hash.h:125

◆ _hash_spareindex()

uint32 _hash_spareindex ( uint32  num_bucket)

Definition at line 143 of file hashutil.c.

References HASH_SPLITPOINT_GROUPS_WITH_ONE_PHASE, HASH_SPLITPOINT_PHASE_BITS, HASH_SPLITPOINT_PHASE_MASK, and pg_ceil_log2_32().

Referenced by _hash_expandtable(), and _hash_init_metabuffer().

144 {
145  uint32 splitpoint_group;
146  uint32 splitpoint_phases;
147 
148  splitpoint_group = pg_ceil_log2_32(num_bucket);
149 
150  if (splitpoint_group < HASH_SPLITPOINT_GROUPS_WITH_ONE_PHASE)
151  return splitpoint_group;
152 
153  /* account for single-phase groups */
154  splitpoint_phases = HASH_SPLITPOINT_GROUPS_WITH_ONE_PHASE;
155 
156  /* account for multi-phase groups before splitpoint_group */
157  splitpoint_phases +=
158  ((splitpoint_group - HASH_SPLITPOINT_GROUPS_WITH_ONE_PHASE) <<
160 
161  /* account for phases within current group */
162  splitpoint_phases +=
163  (((num_bucket - 1) >>
164  (splitpoint_group - (HASH_SPLITPOINT_PHASE_BITS + 1))) &
165  HASH_SPLITPOINT_PHASE_MASK); /* to 0-based value. */
166 
167  return splitpoint_phases;
168 }
#define HASH_SPLITPOINT_PHASE_MASK
Definition: hash.h:232
static uint32 pg_ceil_log2_32(uint32 num)
Definition: pg_bitutils.h:189
#define HASH_SPLITPOINT_PHASE_BITS
Definition: hash.h:230
unsigned int uint32
Definition: c.h:374
#define HASH_SPLITPOINT_GROUPS_WITH_ONE_PHASE
Definition: hash.h:233

◆ hashoptions()

bytea* hashoptions ( Datum  reloptions,
bool  validate 
)

Definition at line 276 of file hashutil.c.

References build_reloptions(), fillfactor, lengthof, offsetof, RELOPT_KIND_HASH, and RELOPT_TYPE_INT.

Referenced by hashhandler().

277 {
278  static const relopt_parse_elt tab[] = {
279  {"fillfactor", RELOPT_TYPE_INT, offsetof(HashOptions, fillfactor)},
280  };
281 
282  return (bytea *) build_reloptions(reloptions, validate,
284  sizeof(HashOptions),
285  tab, lengthof(tab));
286 }
#define lengthof(array)
Definition: c.h:675
void * build_reloptions(Datum reloptions, bool validate, relopt_kind kind, Size relopt_struct_size, const relopt_parse_elt *relopt_elems, int num_relopt_elems)
Definition: reloptions.c:1887
int fillfactor
Definition: pgbench.c:159
Definition: c.h:562
#define offsetof(type, field)
Definition: c.h:668