/* * Calculate hash value for a key */ static uint32 pgss_hash_fn(const void *key, Size keysize) { const pgssHashKey *k = (const pgssHashKey *) key; /* we don't bother to include encoding in the hash */ return hash_uint32((uint32) k->userid) ^ hash_uint32((uint32) k->dbid) ^ DatumGetUInt32(hash_any((const unsigned char *) k->query_ptr, k->query_len)); }
Datum hashname(PG_FUNCTION_ARGS) { char *key = NameStr(*PG_GETARG_NAME(0)); int keylen = strlen(key); Assert(keylen < NAMEDATALEN); /* else it's not truncated * correctly */ return hash_any((unsigned char *) key, keylen); }
/* * Atention! * * Hash function should be changed between mayor pg versions, * don't use text based seed for regres tests! */ Datum dbms_random_seed_varchar(PG_FUNCTION_ARGS) { text *key = PG_GETARG_TEXT_P(0); Datum seed; seed = hash_any((unsigned char *) VARDATA_ANY(key), VARSIZE_ANY_EXHDR(key)); srand((int) seed); PG_RETURN_VOID(); }
/* * hashvarlena() can be used for any varlena datatype in which there are * no non-significant bits, ie, distinct bitpatterns never compare as equal. */ Datum hashvarlena(PG_FUNCTION_ARGS) { struct varlena *key = PG_GETARG_VARLENA_P(0); Datum result; result = hash_any((unsigned char *) VARDATA(key), VARSIZE(key) - VARHDRSZ); /* Avoid leaking memory for toasted inputs */ PG_FREE_IF_COPY(key, 0); return result; }
/* * Select next sampled tuple in current block. * * It is OK here to return an offset without knowing if the tuple is visible * (or even exists). The reason is that we do the coinflip for every tuple * offset in the table. Since all tuples have the same probability of being * returned, it doesn't matter if we do extra coinflips for invisible tuples. * * When we reach end of the block, return InvalidOffsetNumber which tells * SampleScan to go to next block. */ static OffsetNumber bernoulli_nextsampletuple(SampleScanState *node, BlockNumber blockno, OffsetNumber maxoffset) { BernoulliSamplerData *sampler = (BernoulliSamplerData *) node->tsm_state; OffsetNumber tupoffset = sampler->lt; uint32 hashinput[3]; /* Advance to first/next tuple in block */ if (tupoffset == InvalidOffsetNumber) tupoffset = FirstOffsetNumber; else tupoffset++; /* * We compute the hash by applying hash_any to an array of 3 uint32's * containing the block, offset, and seed. This is efficient to set up, * and with the current implementation of hash_any, it gives * machine-independent results, which is a nice property for regression * testing. * * These words in the hash input are the same throughout the block: */ hashinput[0] = blockno; hashinput[2] = sampler->seed; /* * Loop over tuple offsets until finding suitable TID or reaching end of * block. */ for (; tupoffset <= maxoffset; tupoffset++) { uint32 hash; hashinput[1] = tupoffset; hash = DatumGetUInt32(hash_any((const unsigned char *) hashinput, (int) sizeof(hashinput))); if (hash < sampler->cutoff) break; } if (tupoffset > maxoffset) tupoffset = InvalidOffsetNumber; sampler->lt = tupoffset; return tupoffset; }
/* * string_hash: hash function for keys that are null-terminated strings. * * NOTE: this is the default hash function if none is specified. */ uint32 string_hash(const void *key, Size keysize) { /* * If the string exceeds keysize-1 bytes, we want to hash only that many, * because when it is copied into the hash table it will be truncated at * that length. */ Size s_len = strlen((const char *) key); s_len = Min(s_len, keysize - 1); return DatumGetUInt32(hash_any((const unsigned char *) key, (int) s_len)); }
/* * string_hash: hash function for keys that are null-terminated strings. * This is the default hash function if none is specified. */ uint32 string_hash(const void *key, size_t keysize) { /* * If the string exceeds keysize-1 bytes, we want to hash only that * many, because when it is copied into the hash table it will be * truncated at that length. */ size_t s_len; s_len = strlen((const char *) key); s_len = Min(s_len, keysize - 1); return D_TO_UINT32(hash_any((const unsigned char *)key, (int)s_len)); }
Datum decimal64_hash(PG_FUNCTION_ARGS) { PGDecimal64 a = PG_GETARG_DECIMAL64(0); PGDecimal64 n; Datum ret; if (decDoubleIsZero(&a)) { decDoubleZero(&n); } else { decDoubleCanonical(&n, &a); } ret = hash_any((unsigned char *)&n, sizeof(n)); return ret; }
Datum hashfloat8(PG_FUNCTION_ARGS) { float8 key = PG_GETARG_FLOAT8(0); /* * On IEEE-float machines, minus zero and zero have different bit * patterns but should compare as equal. We must ensure that they * have the same hash value, which is most easily done this way: */ if (key == (float8) 0) PG_RETURN_UINT32(0); return hash_any((unsigned char *) &key, sizeof(key)); }
Datum email_hash(PG_FUNCTION_ARGS) { VarChar *str=PG_GETARG_VARCHAR_P(0); char *rt; int32 len,hash_val=0; len=GET_VARSIZE(str); rt=palloc(len+1); memcpy(rt,VARDATA(str),len); rt[len]='\0'; hash_val=hash_any((unsigned char*)rt,len); pfree(rt); PG_RETURN_INT32(hash_val); }
Datum citext_hash(PG_FUNCTION_ARGS) { text *txt = PG_GETARG_TEXT_PP(0); char *str; Datum result; str = str_tolower(VARDATA_ANY(txt), VARSIZE_ANY_EXHDR(txt)); result = hash_any((unsigned char *) str, strlen(str)); pfree(str); /* Avoid leaking memory for toasted inputs */ PG_FREE_IF_COPY(txt, 0); PG_RETURN_DATUM(result); }
/* * Select next block to sample. */ static BlockNumber system_nextsampleblock(SampleScanState *node) { SystemSamplerData *sampler = (SystemSamplerData *) node->tsm_state; HeapScanDesc scan = node->ss.ss_currentScanDesc; BlockNumber nextblock = sampler->nextblock; uint32 hashinput[2]; /* * We compute the hash by applying hash_any to an array of 2 uint32's * containing the block number and seed. This is efficient to set up, and * with the current implementation of hash_any, it gives * machine-independent results, which is a nice property for regression * testing. * * These words in the hash input are the same throughout the block: */ hashinput[1] = sampler->seed; /* * Loop over block numbers until finding suitable block or reaching end of * relation. */ for (; nextblock < scan->rs_nblocks; nextblock++) { uint32 hash; hashinput[0] = nextblock; hash = DatumGetUInt32(hash_any((const unsigned char *) hashinput, (int) sizeof(hashinput))); if (hash < sampler->cutoff) break; } if (nextblock < scan->rs_nblocks) { /* Found a suitable block; remember where we should start next time */ sampler->nextblock = nextblock + 1; return nextblock; } /* Done, but let's reset nextblock to 0 for safety. */ sampler->nextblock = 0; return InvalidBlockNumber; }
int handle_resume_store_req(main_server_st * s, struct proc_st *proc, const SessionResumeStoreReqMsg * req) { tls_cache_st *cache; size_t key; unsigned int max; if (req->session_id.len > GNUTLS_MAX_SESSION_ID) return -1; if (req->session_data.len > MAX_SESSION_DATA_SIZE) return -1; max = MAX(2 * s->config->max_clients, DEFAULT_MAX_CACHED_TLS_SESSIONS); if (s->tls_db.entries >= max) { mslog(s, NULL, LOG_INFO, "maximum number of stored TLS sessions reached (%u)", max); need_maintenance = 1; return -1; } key = hash_any(req->session_id.data, req->session_id.len, 0); cache = talloc(s->tls_db.ht, tls_cache_st); if (cache == NULL) return -1; cache->session_id_size = req->session_id.len; cache->session_data_size = req->session_data.len; cache->remote_addr_len = proc->remote_addr_len; memcpy(cache->session_id, req->session_id.data, req->session_id.len); memcpy(cache->session_data, req->session_data.data, req->session_data.len); memcpy(&cache->remote_addr, &proc->remote_addr, proc->remote_addr_len); htable_add(s->tls_db.ht, key, cache); s->tls_db.entries++; mslog_hex(s, proc, LOG_DEBUG, "TLS session DB storing", req->session_id.data, req->session_id.len, 0); return 0; }
int handle_resume_fetch_req(main_server_st * s, struct proc_st *proc, const SessionResumeFetchMsg * req, SessionResumeReplyMsg * rep) { tls_cache_st *cache; struct htable_iter iter; size_t key; rep->reply = SESSION_RESUME_REPLY_MSG__RESUME__REP__FAILED; key = hash_any(req->session_id.data, req->session_id.len, 0); cache = htable_firstval(s->tls_db.ht, &iter, key); while (cache != NULL) { if (req->session_id.len == cache->session_id_size && memcmp(req->session_id.data, cache->session_id, req->session_id.len) == 0) { if (proc->remote_addr_len == cache->remote_addr_len && ip_cmp(&proc->remote_addr, &cache->remote_addr) == 0) { rep->reply = SESSION_RESUME_REPLY_MSG__RESUME__REP__OK; rep->has_session_data = 1; rep->session_data.data = (void *)cache->session_data; rep->session_data.len = cache->session_data_size; mslog_hex(s, proc, LOG_DEBUG, "TLS session DB resuming", req->session_id.data, req->session_id.len, 0); return 0; } } cache = htable_nextval(s->tls_db.ht, &iter, key); } return 0; }
/* * bpchar needs a specialized hash function because we want to ignore * trailing blanks in comparisons. * * XXX is there any need for locale-specific behavior here? */ Datum hashbpchar(PG_FUNCTION_ARGS) { BpChar *key = PG_GETARG_BPCHAR_P(0); char *keydata; int keylen; Datum result; keydata = VARDATA(key); keylen = bcTruelen(key); result = hash_any((unsigned char *) keydata, keylen); /* Avoid leaking memory for toasted inputs */ PG_FREE_IF_COPY(key, 0); return result; }
static int pam_auth_msg(void* ctx, void *pool, passwd_msg_st *pst) { struct pam_ctx_st * pctx = ctx; size_t prompt_hash = 0; if (pctx->state != PAM_S_INIT && pctx->state != PAM_S_WAIT_FOR_PASS) { return 0; } if (pctx->state == PAM_S_INIT) { /* get the prompt */ pctx->cr_ret = PAM_CONV_ERR; co_call(pctx->cr); if (pctx->cr_ret != PAM_SUCCESS) { syslog(LOG_AUTH, "PAM-auth pam_auth_msg: %s", pam_strerror(pctx->ph, pctx->cr_ret)); return ERR_AUTH_FAIL; } } if (pctx->msg.length == 0) { if (pctx->changing) pst->msg_str = talloc_strdup(pool, "Please enter the new password."); /* else use the default prompt */ } else { if (str_append_data(&pctx->msg, "\0", 1) < 0) return -1; prompt_hash = hash_any(pctx->msg.data, pctx->msg.length, 0); pst->msg_str = talloc_strdup(pool, (char*)pctx->msg.data); } pst->counter = pctx->passwd_counter; /* differentiate password prompts, if the hash of the prompt * is different. */ if (pctx->prev_prompt_hash != prompt_hash) pctx->passwd_counter++; pctx->prev_prompt_hash = prompt_hash; return 0; }
Datum hashtext(PG_FUNCTION_ARGS) { text *key = PG_GETARG_TEXT_P(0); Datum result; /* * Note: this is currently identical in behavior to hashvarlena, but * it seems likely that we may need to do something different in non-C * locales. (See also hashbpchar, if so.) */ result = hash_any((unsigned char *) VARDATA(key), VARSIZE(key) - VARHDRSZ); /* Avoid leaking memory for toasted inputs */ PG_FREE_IF_COPY(key, 0); return result; }
Datum variant_hash(PG_FUNCTION_ARGS) { Variant v = (Variant) PG_DETOAST_DATUM_PACKED(PG_GETARG_DATUM(0)); char *data; int len; Datum result; Assert(fcinfo->flinfo->fn_strict); /* Must be strict */ data = VARDATA_ANY(v); len = VARSIZE_ANY_EXHDR(v); result = hash_any((unsigned char *) data, len); /* Avoid leaking memory for toasted inputs */ PG_FREE_IF_COPY(v, 0); return result; }
Datum hstore_hash(PG_FUNCTION_ARGS) { HStore *hs = PG_GETARG_HS(0); Datum hval = hash_any((unsigned char *) VARDATA(hs), VARSIZE(hs) - VARHDRSZ); /* * this is the only place in the code that cares whether the overall * varlena size exactly matches the true data size; this assertion should * be maintained by all the other code, but we make it explicit here. */ Assert(VARSIZE(hs) == (HS_COUNT(hs) != 0 ? CALCDATASIZE(HS_COUNT(hs), HSE_ENDPOS(ARRPTR(hs)[2 * HS_COUNT(hs) - 1])) : HSHRDSIZE)); PG_FREE_IF_COPY(hs, 0); PG_RETURN_DATUM(hval); }
static long obj_hash(PyObj self) { PyPgTypeInfo typinfo; Datum ob_datum = PyPgObject_GetDatum(self); long rv = 0; typinfo = PyPgTypeInfo(Py_TYPE(self)); if (typinfo->typbyval) { rv = ((long) ob_datum); } else if (typinfo->typlen > -1 && typinfo->typlen <= sizeof(long)) { rv = (*((long *) DatumGetPointer(ob_datum))); } else { int len; switch(typinfo->typlen) { case -2: len = strlen((char *) DatumGetPointer(ob_datum)); break; case -1: len = VARSIZE(ob_datum) - VARHDRSZ; ob_datum = PointerGetDatum(VARDATA(ob_datum)); break; default: len = (int) typinfo->typlen; break; } rv = hash_any((unsigned char *) DatumGetPointer(ob_datum), len); } return(rv); }
static size_t rehash(const void *_e, void *unused) { const client_entry_st *e = _e; return hash_any(e->sid, sizeof(e->sid), 0); }
/* ** Calculate a hash code based on the geometry data alone */ static uint32 geography_hash(GSERIALIZED *g) { return DatumGetUInt32(hash_any((void*)g, VARSIZE(g))); }
/* * tag_hash: hash function for fixed-size tag values */ uint32 tag_hash(const void *key, size_t keysize) { return D_TO_UINT32(hash_any((const unsigned char *)key, (int) keysize)); }
/* hash index support */ datum_t uuid_hash(PG_FUNC_ARGS) { pg_uuid_t *key = ARG_UUID_P(0); return hash_any(key->data, UUID_LEN); }
/* * string_hash: hash function for keys that are null-terminated strings. * * NOTE: this is the default hash function if none is specified. */ uint32 string_hash(const void *key, Size keysize) { return DatumGetUInt32(hash_any((const unsigned char *) key, (int) strlen((const char *) key))); }
static size_t rehash(const void *_e, void *unused) { const char *e = _e; return hash_any(e, strlen(e), 0); }
static size_t rehash_dtls_id(const void* _p, void* unused) { const struct proc_st * proc = _p; return hash_any(proc->dtls_session_id, proc->dtls_session_id_size, 0); }
static size_t rehash_sid(const void* _p, void* unused) { const struct proc_st * proc = _p; return hash_any(proc->sid, sizeof(proc->sid), 0); }
/* * tag_hash: hash function for fixed-size tag values */ uint32 tag_hash(const void *key, Size keysize) { return DatumGetUInt32(hash_any((const unsigned char *) key, (int) keysize)); }
static size_t rehash(const void *_e, void *unused) { const tls_cache_st *e = _e; return hash_any(e->session_id, e->session_id_size, 0); }