summaryrefslogtreecommitdiff
path: root/src/include/access
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2008-09-15 18:43:41 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2008-09-15 18:43:41 +0000
commit4adc2f72a4ccd6e55e594aca837f09130a6af62b (patch)
tree6da4349e66c02ce2d76fe9600ff7ac8aeee741cb /src/include/access
parent440b3384b0741199b4f56a8aac773ecd16aba137 (diff)
Change hash indexes to store only the hash code rather than the whole indexed
value. This means that hash index lookups are always lossy and have to be rechecked when the heap is visited; however, the gain in index compactness outweighs this when the indexed values are wide. Also, we only need to perform datatype comparisons when the hash codes match exactly, rather than for every entry in the hash bucket; so it could also win for datatypes that have expensive comparison functions. A small additional win is gained by keeping hash index pages sorted by hash code and using binary search to reduce the number of index tuples we have to look at. Xiao Meng This commit also incorporates Zdenek Kotala's patch to isolate hash metapages and hash bitmaps a bit better from the page header datastructures.
Diffstat (limited to 'src/include/access')
-rw-r--r--src/include/access/hash.h25
1 files changed, 20 insertions, 5 deletions
diff --git a/src/include/access/hash.h b/src/include/access/hash.h
index 0dab2b6ae91..e00176d4519 100644
--- a/src/include/access/hash.h
+++ b/src/include/access/hash.h
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/include/access/hash.h,v 1.89 2008/07/13 20:45:47 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/access/hash.h,v 1.90 2008/09/15 18:43:41 tgl Exp $
*
* NOTES
* modeled after Margo Seltzer's hash implementation for unix.
@@ -75,6 +75,9 @@ typedef HashPageOpaqueData *HashPageOpaque;
*/
typedef struct HashScanOpaqueData
{
+ /* Hash value of the scan key, ie, the hash key we seek */
+ uint32 hashso_sk_hash;
+
/*
* By definition, a hash scan should be examining only one bucket. We
* record the bucket number here as soon as it is known.
@@ -111,7 +114,7 @@ typedef HashScanOpaqueData *HashScanOpaque;
#define HASH_METAPAGE 0 /* metapage is always block 0 */
#define HASH_MAGIC 0x6440640
-#define HASH_VERSION 1 /* new for Pg 7.4 */
+#define HASH_VERSION 2 /* 2 signifies only hash key value is stored */
/*
* Spares[] holds the number of overflow pages currently allocated at or
@@ -138,7 +141,6 @@ typedef HashScanOpaqueData *HashScanOpaque;
typedef struct HashMetaPageData
{
- PageHeaderData hashm_phdr; /* pad for page header (do not use) */
uint32 hashm_magic; /* magic no. for hash tables */
uint32 hashm_version; /* version ID */
double hashm_ntuples; /* number of tuples stored in the table */
@@ -191,8 +193,16 @@ typedef HashMetaPageData *HashMetaPage;
#define BMPGSZ_BIT(metap) ((metap)->hashm_bmsize << BYTE_TO_BIT)
#define BMPG_SHIFT(metap) ((metap)->hashm_bmshift)
#define BMPG_MASK(metap) (BMPGSZ_BIT(metap) - 1)
-#define HashPageGetBitmap(pg) \
- ((uint32 *) (((char *) (pg)) + MAXALIGN(sizeof(PageHeaderData))))
+
+#define HashPageGetBitmap(page) \
+ ((uint32 *) PageGetContents(page))
+
+#define HashGetMaxBitmapSize(page) \
+ (PageGetPageSize((Page) page) - \
+ (MAXALIGN(SizeOfPageHeaderData) + MAXALIGN(sizeof(HashPageOpaqueData))))
+
+#define HashPageGetMeta(page) \
+ ((HashMetaPage) PageGetContents(page))
/*
* The number of bits in an ovflpage bitmap word.
@@ -330,6 +340,11 @@ extern Bucket _hash_hashkey2bucket(uint32 hashkey, uint32 maxbucket,
uint32 highmask, uint32 lowmask);
extern uint32 _hash_log2(uint32 num);
extern void _hash_checkpage(Relation rel, Buffer buf, int flags);
+extern uint32 _hash_get_indextuple_hashkey(IndexTuple itup);
+extern IndexTuple _hash_form_tuple(Relation index,
+ Datum *values, bool *isnull);
+extern OffsetNumber _hash_binsearch(Page page, uint32 hash_value);
+extern OffsetNumber _hash_binsearch_last(Page page, uint32 hash_value);
/* hash.c */
extern void hash_redo(XLogRecPtr lsn, XLogRecord *record);