Pre-hash strings from str(),hex(),oct(),bin() conversions

This commit is contained in:
K. Lange 2022-09-13 19:46:17 +09:00
parent 08aa30a7c0
commit 8043ca2183
5 changed files with 23 additions and 9 deletions

View File

@ -4,6 +4,8 @@
#include <kuroko/memory.h>
#include <kuroko/util.h>
#include "private.h"
struct ByteArray {
KrkInstance inst;
KrkValue actual;
@ -61,7 +63,7 @@ KRK_Method(bytes,__hash__) {
/* This is the so-called "sdbm" hash. It comes from a piece of
* public domain code from a clone of ndbm. */
for (size_t i = 0; i < self->length; ++i) {
hash = (int)self->bytes[i] + (hash << 6) + (hash << 16) - hash;
krk_hash_advance(hash,self->bytes[i]);
}
return INTEGER_VAL(hash);
}

View File

@ -20,6 +20,7 @@
#include <kuroko/vm.h>
#include <kuroko/value.h>
#include <kuroko/util.h>
#include "private.h"
#define DIGIT_SHIFT 31
#define DIGIT_MAX 0x7FFFFFFF
@ -1006,7 +1007,7 @@ static char * _fast_conversion(const KrkLong * abs, unsigned int bits, char * wr
/**
* @brief Convert a long to a string in a given base.
*/
static char * krk_long_to_str(const KrkLong * n, int _base, const char * prefix, size_t *size) {
static char * krk_long_to_str(const KrkLong * n, int _base, const char * prefix, size_t *size, uint32_t *_hash) {
KrkLong abs;
krk_long_init_si(&abs, 0);
@ -1039,11 +1040,14 @@ static char * krk_long_to_str(const KrkLong * n, int _base, const char * prefix,
char * rev = malloc(len);
char * out = rev;
uint32_t hash = 0;
while (writer != tmp) {
writer--;
*out++ = *writer;
*out = *--writer;
krk_hash_advance(hash,*out);
out++;
}
*out = '\0';
*_hash = hash;
free(tmp);
@ -1377,8 +1381,9 @@ KRK_Method(long,__rtruediv__) {
#define PRINTER(name,base,prefix) \
KRK_Method(long,__ ## name ## __) { \
size_t size; \
char * rev = krk_long_to_str(self->value, base, prefix, &size); \
return OBJECT_VAL(krk_takeString(rev,size)); \
uint32_t hash; \
char * rev = krk_long_to_str(self->value, base, prefix, &size, &hash); \
return OBJECT_VAL(krk_takeStringVetted(rev,size,size,KRK_OBJ_FLAGS_STRING_ASCII,hash)); \
}
PRINTER(str,10,"")

View File

@ -71,7 +71,7 @@ KRK_Method(str,__add__) {
/* Hashes can be extended, which saves us calculating the whole thing */
uint32_t hash = self->obj.hash;
for (size_t i = 0; i < bl; ++i) {
hash = (int)b[i] + (hash << 6) + (hash << 16) - hash;
krk_hash_advance(hash,b[i]);
}
KrkString * result = krk_takeStringVetted(chars, length, cpLength, type, hash);
@ -390,7 +390,7 @@ KRK_Method(str,__mul__) {
for (krk_integer_type i = 0; i < howMany; ++i) {
for (size_t j = 0; j < self->length; ++j) {
*c = self->chars[j];
hash = (int)*c + (hash << 6) + (hash << 16) - hash;
krk_hash_advance(hash, *c);
c++;
}
}

View File

@ -8,6 +8,8 @@
#include <kuroko/vm.h>
#include <kuroko/table.h>
#include "private.h"
#define ALLOCATE_OBJECT(type, objectType) \
(type*)allocateObject(sizeof(type), objectType)
@ -195,7 +197,7 @@ static uint32_t hashString(const char * key, size_t length) {
/* This is the so-called "sdbm" hash. It comes from a piece of
* public domain code from a clone of ndbm. */
for (size_t i = 0; i < length; ++i) {
hash = (int)key[i] + (hash << 6) + (hash << 16) - hash;
krk_hash_advance(hash,key[i]);
}
return hash;
}

View File

@ -62,3 +62,8 @@ struct ParsedFormatSpec {
int hasPrecision;
int fillSize;
};
/* We inline hashing in a few places, so it's nice to have this in one place.
* This is the "sdbm" hash. I've been using it in various places for many years,
* and this specific version apparently traces to gawk. */
#define krk_hash_advance(hash,c) do { hash = (int)(c) + (hash << 6) + (hash << 16) - hash; } while (0)