Header And Logo

PostgreSQL
| The world's most advanced open source database.

Functions

hashutil.c File Reference

#include "postgres.h"
#include "access/hash.h"
#include "access/reloptions.h"
#include "access/relscan.h"
#include "utils/lsyscache.h"
#include "utils/rel.h"
Include dependency graph for hashutil.c:

Go to the source code of this file.

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_log2 (uint32 num)
void _hash_checkpage (Relation rel, Buffer buf, int flags)
Datum hashoptions (PG_FUNCTION_ARGS)
uint32 _hash_get_indextuple_hashkey (IndexTuple itup)
IndexTuple _hash_form_tuple (Relation index, Datum *values, bool *isnull)
OffsetNumber _hash_binsearch (Page page, uint32 hash_value)
OffsetNumber _hash_binsearch_last (Page page, uint32 hash_value)

Function Documentation

OffsetNumber _hash_binsearch ( Page  page,
uint32  hash_value 
)

Definition at line 287 of file hashutil.c.

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

Referenced by _hash_pgaddtup(), and _hash_step().

{
    OffsetNumber upper;
    OffsetNumber lower;

    /* Loop invariant: lower <= desired place <= upper */
    upper = PageGetMaxOffsetNumber(page) + 1;
    lower = FirstOffsetNumber;

    while (upper > lower)
    {
        OffsetNumber off;
        IndexTuple  itup;
        uint32      hashkey;

        off = (upper + lower) / 2;
        Assert(OffsetNumberIsValid(off));

        itup = (IndexTuple) PageGetItem(page, PageGetItemId(page, off));
        hashkey = _hash_get_indextuple_hashkey(itup);
        if (hashkey < hash_value)
            lower = off + 1;
        else
            upper = off;
    }

    return lower;
}

OffsetNumber _hash_binsearch_last ( Page  page,
uint32  hash_value 
)

Definition at line 325 of file hashutil.c.

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

Referenced by _hash_step().

{
    OffsetNumber upper;
    OffsetNumber lower;

    /* Loop invariant: lower <= desired place <= upper */
    upper = PageGetMaxOffsetNumber(page);
    lower = FirstOffsetNumber - 1;

    while (upper > lower)
    {
        IndexTuple  itup;
        OffsetNumber off;
        uint32      hashkey;

        off = (upper + lower + 1) / 2;
        Assert(OffsetNumberIsValid(off));

        itup = (IndexTuple) PageGetItem(page, PageGetItemId(page, off));
        hashkey = _hash_get_indextuple_hashkey(itup);
        if (hashkey > hash_value)
            upper = off - 1;
        else
            lower = off;
    }

    return lower;
}

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

Definition at line 156 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_first(), _hash_freeovflpage(), _hash_getbuf(), _hash_getbuf_with_strategy(), _hash_getovflpage(), _hash_next(), _hash_pgaddtup(), and _hash_step().

{
    Page        page = BufferGetPage(buf);

    /*
     * ReadBuffer verifies that every newly-read page passes
     * PageHeaderIsValid, which means it either contains a reasonably sane
     * page header or is all-zero.  We have to defend against the all-zero
     * case, however.
     */
    if (PageIsNew(page))
        ereport(ERROR,
                (errcode(ERRCODE_INDEX_CORRUPTED),
             errmsg("index \"%s\" contains unexpected zero page at block %u",
                    RelationGetRelationName(rel),
                    BufferGetBlockNumber(buf)),
                 errhint("Please REINDEX it.")));

    /*
     * Additionally check that the special area looks sane.
     */
    if (PageGetSpecialSize(page) != MAXALIGN(sizeof(HashPageOpaqueData)))
        ereport(ERROR,
                (errcode(ERRCODE_INDEX_CORRUPTED),
                 errmsg("index \"%s\" contains corrupted page at block %u",
                        RelationGetRelationName(rel),
                        BufferGetBlockNumber(buf)),
                 errhint("Please REINDEX it.")));

    if (flags)
    {
        HashPageOpaque opaque = (HashPageOpaque) PageGetSpecialPointer(page);

        if ((opaque->hasho_flag & flags) == 0)
            ereport(ERROR,
                    (errcode(ERRCODE_INDEX_CORRUPTED),
                   errmsg("index \"%s\" contains corrupted page at block %u",
                          RelationGetRelationName(rel),
                          BufferGetBlockNumber(buf)),
                     errhint("Please REINDEX it.")));
    }

    /*
     * When checking the metapage, also verify magic number and version.
     */
    if (flags == LH_META_PAGE)
    {
        HashMetaPage metap = HashPageGetMeta(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",
                            RelationGetRelationName(rel)),
                     errhint("Please REINDEX it.")));
    }
}

bool _hash_checkqual ( IndexScanDesc  scan,
IndexTuple  itup 
)

Definition at line 28 of file hashutil.c.

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

Referenced by _hash_step().

{
    /*
     * Currently, we can't check any of the scan conditions since we do not
     * have the original index entry value to supply to the sk_func. Always
     * return true; we expect that hashgettuple already set the recheck flag
     * to make the main indexscan code do it.
     */
#ifdef NOT_USED
    TupleDesc   tupdesc = RelationGetDescr(scan->indexRelation);
    ScanKey     key = scan->keyData;
    int         scanKeySize = scan->numberOfKeys;

    while (scanKeySize > 0)
    {
        Datum       datum;
        bool        isNull;
        Datum       test;

        datum = index_getattr(itup,
                              key->sk_attno,
                              tupdesc,
                              &isNull);

        /* assume sk_func is strict */
        if (isNull)
            return false;
        if (key->sk_flags & SK_ISNULL)
            return false;

        test = FunctionCall2Coll(&key->sk_func, key->sk_collation,
                                 datum, key->sk_argument);

        if (!DatumGetBool(test))
            return false;

        key++;
        scanKeySize--;
    }
#endif

    return true;
}

uint32 _hash_datum2hashkey ( Relation  rel,
Datum  key 
)

Definition at line 79 of file hashutil.c.

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

Referenced by _hash_first(), and _hash_form_tuple().

{
    FmgrInfo   *procinfo;
    Oid         collation;

    /* XXX assumes index has only one attribute */
    procinfo = index_getprocinfo(rel, 1, HASHPROC);
    collation = rel->rd_indcollation[0];

    return DatumGetUInt32(FunctionCall1Coll(procinfo, collation, key));
}

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

Definition at line 99 of file hashutil.c.

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

Referenced by _hash_first().

{
    RegProcedure hash_proc;
    Oid         collation;

    /* XXX assumes index has only one attribute */
    hash_proc = get_opfamily_proc(rel->rd_opfamily[0],
                                  keytype,
                                  keytype,
                                  HASHPROC);
    if (!RegProcedureIsValid(hash_proc))
        elog(ERROR, "missing support function %d(%u,%u) for index \"%s\"",
             HASHPROC, keytype, keytype,
             RelationGetRelationName(rel));
    collation = rel->rd_indcollation[0];

    return DatumGetUInt32(OidFunctionCall1Coll(hash_proc, collation, key));
}

IndexTuple _hash_form_tuple ( Relation  index,
Datum values,
bool isnull 
)

Definition at line 254 of file hashutil.c.

References _hash_datum2hashkey(), Assert, index_form_tuple(), tupleDesc::natts, RelationGetDescr, and UInt32GetDatum.

Referenced by hashbuildCallback(), and hashinsert().

{
    IndexTuple  itup;
    uint32      hashkey;
    Datum       hashkeydatum;
    TupleDesc   hashdesc;

    if (isnull[0])
        hashkeydatum = (Datum) 0;
    else
    {
        hashkey = _hash_datum2hashkey(index, values[0]);
        hashkeydatum = UInt32GetDatum(hashkey);
    }
    hashdesc = RelationGetDescr(index);
    Assert(hashdesc->natts == 1);
    itup = index_form_tuple(hashdesc, &hashkeydatum, isnull);
    return itup;
}

uint32 _hash_get_indextuple_hashkey ( IndexTuple  itup  ) 

Definition at line 238 of file hashutil.c.

References IndexInfoFindDataOffset, and IndexTupleData::t_info.

Referenced by _hash_binsearch(), _hash_binsearch_last(), _hash_doinsert(), _hash_pgaddtup(), _hash_splitbucket(), and _hash_step().

{
    char       *attp;

    /*
     * We assume the hash key is the first attribute and can't be null, so
     * this can be done crudely but very very cheaply ...
     */
    attp = (char *) itup + IndexInfoFindDataOffset(itup->t_info);
    return *((uint32 *) attp);
}

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

Definition at line 122 of file hashutil.c.

Referenced by _hash_doinsert(), _hash_first(), and _hash_splitbucket().

{
    Bucket      bucket;

    bucket = hashkey & highmask;
    if (bucket > maxbucket)
        bucket = bucket & lowmask;

    return bucket;
}

uint32 _hash_log2 ( uint32  num  ) 

Definition at line 138 of file hashutil.c.

References i.

Referenced by _h_spoolinit(), _hash_expandtable(), and _hash_metapinit().

{
    uint32      i,
                limit;

    limit = 1;
    for (i = 0; limit < num; limit <<= 1, i++)
        ;
    return i;
}

Datum hashoptions ( PG_FUNCTION_ARGS   ) 

Definition at line 221 of file hashutil.c.

References default_reloptions(), PG_GETARG_BOOL, PG_GETARG_DATUM, PG_RETURN_BYTEA_P, PG_RETURN_NULL, and RELOPT_KIND_HASH.

{
    Datum       reloptions = PG_GETARG_DATUM(0);
    bool        validate = PG_GETARG_BOOL(1);
    bytea      *result;

    result = default_reloptions(reloptions, validate, RELOPT_KIND_HASH);

    if (result)
        PG_RETURN_BYTEA_P(result);
    PG_RETURN_NULL();
}