/*@ behavior error: assumes sponge == \null; ensures \result == 0; assigns \nothing; behavior success: assumes sponge != \null; requires \valid(sponge); ensures \result == 0; ensures sponge_invariant(sponge); assigns sponge->a[0..24], sponge->flags, sponge->squeezed, sponge->absorbed; complete behaviors; disjoint behaviors; */ int sha3_512_init(register keccak_sponge* const restrict sponge) { checknull(sponge); int err = _hash_init(sponge, 200 - (64 * 2), flag_sha3_512 ^ hash_absorbing); //@ assert err == 0; HANDLE_ERR; return 0; } /*@ predicate sha3_512_update_err(keccak_sponge* sponge, uint8_t* in) = (sponge == \null) || (in == \null) || (sponge->flags != (flag_sha3_512 ^ hash_absorbing)); */ /*@ behavior error: assumes sha3_512_update_err(sponge, in); ensures \result < 0; assigns \nothing; behavior success: assumes !sha3_512_update_err(sponge, in);
/* * hashbuild() -- build a new hash index. */ IndexBuildResult * hashbuild(Relation heap, Relation index, IndexInfo *indexInfo) { IndexBuildResult *result; BlockNumber relpages; double reltuples; double allvisfrac; uint32 num_buckets; long sort_threshold; HashBuildState buildstate; /* * We expect to be called exactly once for any index relation. If that's * not the case, big trouble's what we have. */ if (RelationGetNumberOfBlocks(index) != 0) elog(ERROR, "index \"%s\" already contains data", RelationGetRelationName(index)); /* Estimate the number of rows currently present in the table */ estimate_rel_size(heap, NULL, &relpages, &reltuples, &allvisfrac); /* Initialize the hash index metadata page and initial buckets */ num_buckets = _hash_init(index, reltuples, MAIN_FORKNUM); /* * If we just insert the tuples into the index in scan order, then * (assuming their hash codes are pretty random) there will be no locality * of access to the index, and if the index is bigger than available RAM * then we'll thrash horribly. To prevent that scenario, we can sort the * tuples by (expected) bucket number. However, such a sort is useless * overhead when the index does fit in RAM. We choose to sort if the * initial index size exceeds maintenance_work_mem, or the number of * buffers usable for the index, whichever is less. (Limiting by the * number of buffers should reduce thrashing between PG buffers and kernel * buffers, which seems useful even if no physical I/O results. Limiting * by maintenance_work_mem is useful to allow easy testing of the sort * code path, and may be useful to DBAs as an additional control knob.) * * NOTE: this test will need adjustment if a bucket is ever different from * one page. Also, "initial index size" accounting does not include the * metapage, nor the first bitmap page. */ sort_threshold = (maintenance_work_mem * 1024L) / BLCKSZ; if (index->rd_rel->relpersistence != RELPERSISTENCE_TEMP) sort_threshold = Min(sort_threshold, NBuffers); else sort_threshold = Min(sort_threshold, NLocBuffer); if (num_buckets >= (uint32) sort_threshold) buildstate.spool = _h_spoolinit(heap, index, num_buckets); else buildstate.spool = NULL; /* prepare to build the index */ buildstate.indtuples = 0; buildstate.heapRel = heap; /* do the heap scan */ reltuples = IndexBuildHeapScan(heap, index, indexInfo, true, hashbuildCallback, (void *) &buildstate); if (buildstate.spool) { /* sort the tuples and insert them into the index */ _h_indexbuild(buildstate.spool, buildstate.heapRel); _h_spooldestroy(buildstate.spool); } /* * Return statistics */ result = (IndexBuildResult *) palloc(sizeof(IndexBuildResult)); result->heap_tuples = reltuples; result->index_tuples = buildstate.indtuples; return result; }
/* * hashbuildempty() -- build an empty hash index in the initialization fork */ void hashbuildempty(Relation index) { _hash_init(index, 0, INIT_FORKNUM); }
/*@ behavior error: assumes sponge == \null; ensures \result == 0; assigns \nothing; behavior success: assumes sponge != \null; requires \valid(sponge); ensures \result == 0; ensures sponge_invariant(sponge); assigns sponge->a[0..24], sponge->flags, sponge->squeezed, sponge->absorbed; complete behaviors; disjoint behaviors; */ int sha3_224_init(register keccak_sponge* const restrict sponge) { checknull(sponge); int err = _hash_init(sponge, 200 - (28 * 2), flag_sha3_224 ^ hash_absorbing); //@ assert err == 0; HANDLE_ERR; return 0; } /*@ predicate sha3_224_update_err(keccak_sponge* sponge, uint8_t* in) = (sponge == \null) || (in == \null) || (sponge->flags != (flag_sha3_224 ^ hash_absorbing)); */ /*@ behavior error: assumes sha3_224_update_err(sponge, in); ensures \result < 0; assigns \nothing; behavior success: assumes !sha3_224_update_err(sponge, in);