mirror of
https://github.com/postgres/postgres.git
synced 2025-08-27 07:42:10 +03:00
148 lines
3.0 KiB
C
148 lines
3.0 KiB
C
/*-------------------------------------------------------------------------
|
|
*
|
|
* btutils.c
|
|
* Utility code for Postgres btree implementation.
|
|
*
|
|
* Copyright (c) 1994, Regents of the University of California
|
|
*
|
|
*
|
|
* IDENTIFICATION
|
|
* $Header: /cvsroot/pgsql/src/backend/access/hash/hashutil.c,v 1.15 1999/02/13 23:14:21 momjian Exp $
|
|
*
|
|
*-------------------------------------------------------------------------
|
|
*/
|
|
|
|
#include <postgres.h>
|
|
|
|
#include <access/hash.h>
|
|
#include <fmgr.h>
|
|
#include <utils/memutils.h>
|
|
#include <access/iqual.h>
|
|
|
|
#ifndef HAVE_MEMMOVE
|
|
#include <regex/utils.h>
|
|
#else
|
|
#include <string.h>
|
|
#endif
|
|
|
|
ScanKey
|
|
_hash_mkscankey(Relation rel, IndexTuple itup, HashMetaPage metap)
|
|
{
|
|
ScanKey skey;
|
|
TupleDesc itupdesc;
|
|
int natts;
|
|
AttrNumber i;
|
|
Datum arg;
|
|
RegProcedure proc;
|
|
bool null;
|
|
|
|
natts = rel->rd_rel->relnatts;
|
|
itupdesc = RelationGetDescr(rel);
|
|
|
|
skey = (ScanKey) palloc(natts * sizeof(ScanKeyData));
|
|
|
|
for (i = 0; i < natts; i++)
|
|
{
|
|
arg = index_getattr(itup, i + 1, itupdesc, &null);
|
|
proc = metap->hashm_procid;
|
|
ScanKeyEntryInitialize(&skey[i],
|
|
0x0, (AttrNumber) (i + 1), proc, arg);
|
|
}
|
|
|
|
return skey;
|
|
}
|
|
|
|
void
|
|
_hash_freeskey(ScanKey skey)
|
|
{
|
|
pfree(skey);
|
|
}
|
|
|
|
|
|
bool
|
|
_hash_checkqual(IndexScanDesc scan, IndexTuple itup)
|
|
{
|
|
if (scan->numberOfKeys > 0)
|
|
return (index_keytest(itup,
|
|
RelationGetDescr(scan->relation),
|
|
scan->numberOfKeys, scan->keyData));
|
|
else
|
|
return true;
|
|
}
|
|
|
|
HashItem
|
|
_hash_formitem(IndexTuple itup)
|
|
{
|
|
int nbytes_hitem;
|
|
HashItem hitem;
|
|
Size tuplen;
|
|
|
|
/* disallow nulls in hash keys */
|
|
if (itup->t_info & INDEX_NULL_MASK)
|
|
elog(ERROR, "hash indices cannot include null keys");
|
|
|
|
/* make a copy of the index tuple with room for the sequence number */
|
|
tuplen = IndexTupleSize(itup);
|
|
nbytes_hitem = tuplen +
|
|
(sizeof(HashItemData) - sizeof(IndexTupleData));
|
|
|
|
hitem = (HashItem) palloc(nbytes_hitem);
|
|
memmove((char *) &(hitem->hash_itup), (char *) itup, tuplen);
|
|
|
|
return hitem;
|
|
}
|
|
|
|
Bucket
|
|
_hash_call(Relation rel, HashMetaPage metap, Datum key)
|
|
{
|
|
uint32 n;
|
|
Bucket bucket;
|
|
RegProcedure proc;
|
|
|
|
proc = metap->hashm_procid;
|
|
n = (uint32) fmgr(proc, key);
|
|
bucket = n & metap->hashm_highmask;
|
|
if (bucket > metap->hashm_maxbucket)
|
|
bucket = bucket & metap->hashm_lowmask;
|
|
return bucket;
|
|
}
|
|
|
|
/*
|
|
* _hash_log2 -- returns ceil(lg2(num))
|
|
*/
|
|
uint32
|
|
_hash_log2(uint32 num)
|
|
{
|
|
uint32 i,
|
|
limit;
|
|
|
|
limit = 1;
|
|
for (i = 0; limit < num; limit = limit << 1, i++)
|
|
;
|
|
return i;
|
|
}
|
|
|
|
/*
|
|
* _hash_checkpage -- sanity checks on the format of all hash pages
|
|
*/
|
|
void
|
|
_hash_checkpage(Page page, int flags)
|
|
{
|
|
HashPageOpaque opaque;
|
|
|
|
Assert(page);
|
|
Assert(((PageHeader) (page))->pd_lower >= (sizeof(PageHeaderData) - sizeof(ItemIdData)));
|
|
#if 1
|
|
Assert(((PageHeader) (page))->pd_upper <=
|
|
(BLCKSZ - DOUBLEALIGN(sizeof(HashPageOpaqueData))));
|
|
Assert(((PageHeader) (page))->pd_special ==
|
|
(BLCKSZ - DOUBLEALIGN(sizeof(HashPageOpaqueData))));
|
|
Assert(((PageHeader) (page))->pd_opaque.od_pagesize == BLCKSZ);
|
|
#endif
|
|
if (flags)
|
|
{
|
|
opaque = (HashPageOpaque) PageGetSpecialPointer(page);
|
|
Assert(opaque->hasho_flag & flags);
|
|
}
|
|
}
|