summaryrefslogtreecommitdiff
path: root/src/backend/access/hash/hashutil.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/access/hash/hashutil.c')
-rw-r--r--src/backend/access/hash/hashutil.c130
1 files changed, 67 insertions, 63 deletions
diff --git a/src/backend/access/hash/hashutil.c b/src/backend/access/hash/hashutil.c
index 83126fccb42..f3ac58085bc 100644
--- a/src/backend/access/hash/hashutil.c
+++ b/src/backend/access/hash/hashutil.c
@@ -8,11 +8,10 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/access/hash/hashutil.c,v 1.33 2003/08/04 02:39:57 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/access/hash/hashutil.c,v 1.33.2.1 2003/09/07 04:36:47 momjian Exp $
*
*-------------------------------------------------------------------------
*/
-
#include "postgres.h"
#include "access/genam.h"
@@ -20,55 +19,19 @@
#include "access/iqual.h"
-ScanKey
-_hash_mkscankey(Relation rel, IndexTuple itup)
-{
- ScanKey skey;
- TupleDesc itupdesc;
- int natts;
- AttrNumber i;
- Datum arg;
- FmgrInfo *procinfo;
- bool isnull;
-
- 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, &isnull);
- procinfo = index_getprocinfo(rel, i + 1, HASHPROC);
- ScanKeyEntryInitializeWithInfo(&skey[i],
- 0x0,
- (AttrNumber) (i + 1),
- procinfo,
- CurrentMemoryContext,
- arg);
- }
-
- return skey;
-}
-
-void
-_hash_freeskey(ScanKey skey)
-{
- pfree(skey);
-}
-
-
+/*
+ * _hash_checkqual -- does the index tuple satisfy the scan conditions?
+ */
bool
_hash_checkqual(IndexScanDesc scan, IndexTuple itup)
{
- if (scan->numberOfKeys > 0)
- return (index_keytest(itup,
- RelationGetDescr(scan->indexRelation),
- scan->numberOfKeys, scan->keyData));
- else
- return true;
+ return index_keytest(itup, RelationGetDescr(scan->indexRelation),
+ scan->numberOfKeys, scan->keyData);
}
+/*
+ * _hash_formitem -- construct a hash index entry
+ */
HashItem
_hash_formitem(IndexTuple itup)
{
@@ -82,30 +45,49 @@ _hash_formitem(IndexTuple itup)
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("hash indexes cannot include null keys")));
- /* make a copy of the index tuple with room for the sequence number */
+ /*
+ * make a copy of the index tuple (XXX do we still need to copy?)
+ *
+ * HashItemData used to have more fields than IndexTupleData, but no
+ * longer...
+ */
tuplen = IndexTupleSize(itup);
nbytes_hitem = tuplen +
(sizeof(HashItemData) - sizeof(IndexTupleData));
hitem = (HashItem) palloc(nbytes_hitem);
- memmove((char *) &(hitem->hash_itup), (char *) itup, tuplen);
+ memcpy((char *) &(hitem->hash_itup), (char *) itup, tuplen);
return hitem;
}
-Bucket
-_hash_call(Relation rel, HashMetaPage metap, Datum key)
+/*
+ * _hash_datum2hashkey -- given a Datum, call the index's hash procedure
+ */
+uint32
+_hash_datum2hashkey(Relation rel, Datum key)
{
FmgrInfo *procinfo;
- uint32 n;
- Bucket bucket;
/* XXX assumes index has only one attribute */
procinfo = index_getprocinfo(rel, 1, HASHPROC);
- n = DatumGetUInt32(FunctionCall1(procinfo, key));
- bucket = n & metap->hashm_highmask;
- if (bucket > metap->hashm_maxbucket)
- bucket = bucket & metap->hashm_lowmask;
+
+ return DatumGetUInt32(FunctionCall1(procinfo, key));
+}
+
+/*
+ * _hash_hashkey2bucket -- determine which bucket the hashkey maps to.
+ */
+Bucket
+_hash_hashkey2bucket(uint32 hashkey, uint32 maxbucket,
+ uint32 highmask, uint32 lowmask)
+{
+ Bucket bucket;
+
+ bucket = hashkey & highmask;
+ if (bucket > maxbucket)
+ bucket = bucket & lowmask;
+
return bucket;
}
@@ -119,7 +101,7 @@ _hash_log2(uint32 num)
limit;
limit = 1;
- for (i = 0; limit < num; limit = limit << 1, i++)
+ for (i = 0; limit < num; limit <<= 1, i++)
;
return i;
}
@@ -128,22 +110,44 @@ _hash_log2(uint32 num)
* _hash_checkpage -- sanity checks on the format of all hash pages
*/
void
-_hash_checkpage(Page page, int flags)
+_hash_checkpage(Relation rel, Page page, int flags)
{
- HashPageOpaque opaque;
-
Assert(page);
+ /*
+ * When checking the metapage, always verify magic number and version.
+ */
+ if (flags == LH_META_PAGE)
+ {
+ HashMetaPage metap = (HashMetaPage) page;
+
+ if (metap->hashm_magic != HASH_MAGIC)
+ ereport(ERROR,
+ (errcode(ERRCODE_INDEX_CORRUPTED),
+ errmsg("index \"%s\" is not a hash index",
+ RelationGetRelationName(rel))));
+
+ if (metap->hashm_version != HASH_VERSION)
+ ereport(ERROR,
+ (errcode(ERRCODE_INDEX_CORRUPTED),
+ errmsg("index \"%s\" has wrong hash version, please REINDEX it",
+ RelationGetRelationName(rel))));
+ }
+
+ /*
+ * These other checks are for debugging purposes only.
+ */
+#ifdef USE_ASSERT_CHECKING
Assert(((PageHeader) (page))->pd_lower >= SizeOfPageHeaderData);
-#if 1
Assert(((PageHeader) (page))->pd_upper <=
(BLCKSZ - MAXALIGN(sizeof(HashPageOpaqueData))));
Assert(((PageHeader) (page))->pd_special ==
(BLCKSZ - MAXALIGN(sizeof(HashPageOpaqueData))));
Assert(PageGetPageSize(page) == BLCKSZ);
-#endif
if (flags)
{
- opaque = (HashPageOpaque) PageGetSpecialPointer(page);
+ HashPageOpaque opaque = (HashPageOpaque) PageGetSpecialPointer(page);
+
Assert(opaque->hasho_flag & flags);
}
+#endif /* USE_ASSERT_CHECKING */
}