delete unused funcs
This commit is contained in:
@@ -14,7 +14,6 @@
|
|||||||
|
|
||||||
#define CACHE_SIZE 512
|
#define CACHE_SIZE 512
|
||||||
#define PIVOT_SIZE 486
|
#define PIVOT_SIZE 486
|
||||||
#define SENTINELS 0
|
|
||||||
|
|
||||||
struct set {
|
struct set {
|
||||||
size_t cnt;
|
size_t cnt;
|
||||||
@@ -138,6 +137,8 @@ static void sort_symbols(struct symbols* values, size_t count, int bpp) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (source != values) memcpy(values, source, count * sizeof(*values));
|
if (source != values) memcpy(values, source, count * sizeof(*values));
|
||||||
|
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---
|
// ---
|
||||||
@@ -187,51 +188,6 @@ static int encode_set_size(int cnt, int bpp) {
|
|||||||
|
|
||||||
// ---
|
// ---
|
||||||
|
|
||||||
static void encode_delta(int cnt, unsigned* hash_pt) {
|
|
||||||
assert(cnt > 0);
|
|
||||||
|
|
||||||
unsigned* end_pt = hash_pt + cnt;
|
|
||||||
unsigned prev_hash = *hash_pt++;
|
|
||||||
|
|
||||||
while (hash_pt < end_pt) {
|
|
||||||
*hash_pt -= prev_hash;
|
|
||||||
prev_hash += *hash_pt++;
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Main golomb encoding routine: package integers into bits.
|
|
||||||
// http://algo2.iti.uni-karlsruhe.de/singler/publications/cacheefficientbloomfilters-wea2007.pdf
|
|
||||||
// The first integer is then stored in unary coding (which is a variable-length
|
|
||||||
// sequence of '0' followed by a terminating '1'); the second part is stored in
|
|
||||||
// normal binary coding (using Mshift bits).
|
|
||||||
static int encode_golomb(int cnt, const unsigned* delta_pt, int Mshift, char* bit_pt) {
|
|
||||||
char* start_pt = bit_pt;
|
|
||||||
const unsigned mask = (1u << Mshift) - 1;
|
|
||||||
|
|
||||||
for (int i = 0; i < cnt; ++i) {
|
|
||||||
unsigned elem = *delta_pt++;
|
|
||||||
|
|
||||||
// first part: variable-length sequence
|
|
||||||
unsigned q = elem >> Mshift;
|
|
||||||
for (int j = 0; j < (int)q; ++j) {
|
|
||||||
*bit_pt++ = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
*bit_pt++ = 1;
|
|
||||||
|
|
||||||
// second part: lower Mshift bits
|
|
||||||
unsigned r = elem & mask;
|
|
||||||
for (int j = 0; j < Mshift; ++j) {
|
|
||||||
*bit_pt++ = r & 1;
|
|
||||||
r >>= 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return bit_pt - start_pt;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Main base62 encoding routine: pack bit_arr into base62 string.
|
// Main base62 encoding routine: pack bit_arr into base62 string.
|
||||||
/*
|
/*
|
||||||
* Base62 routines - encode bits with alnum characters.
|
* Base62 routines - encode bits with alnum characters.
|
||||||
@@ -260,69 +216,10 @@ static char* bits_to_char(int c, char* base62) {
|
|||||||
return base62;
|
return base62;
|
||||||
}
|
}
|
||||||
|
|
||||||
// filling from the least significant bits, in case of Z - put in the most
|
|
||||||
// significant bits
|
|
||||||
static int encode_base62(int bit_cnt, const char* bit_pt, char* base62_str_pt) {
|
|
||||||
char* base62_start = base62_str_pt;
|
|
||||||
|
|
||||||
int bits2 = 0; // number of high bits set
|
|
||||||
int bits6 = 0; // number of regular bits set
|
|
||||||
int num6b = 0; // pending 6-bit number
|
|
||||||
|
|
||||||
while (bit_cnt-- > 0) {
|
|
||||||
num6b |= (*bit_pt++ << bits6++);
|
|
||||||
|
|
||||||
if (bits6 + bits2 < 6) continue;
|
|
||||||
|
|
||||||
if (num6b >= 61) { // 61 62 63 cases
|
|
||||||
base62_str_pt = bits_to_char(61, base62_str_pt);
|
|
||||||
bits2 = 2;
|
|
||||||
num6b = (num6b - 61) << 4; // (0|16|32) in high bits
|
|
||||||
} else {
|
|
||||||
assert(num6b < 61);
|
|
||||||
base62_str_pt = bits_to_char(num6b, base62_str_pt);
|
|
||||||
bits2 = 0;
|
|
||||||
num6b = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
bits6 = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (bits6 + bits2) {
|
|
||||||
assert(num6b < 61);
|
|
||||||
base62_str_pt = bits_to_char(num6b, base62_str_pt);
|
|
||||||
}
|
|
||||||
|
|
||||||
*base62_str_pt = '\0';
|
|
||||||
|
|
||||||
return base62_str_pt - base62_start;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ---
|
// ---
|
||||||
|
|
||||||
static inline char encode_bpp(int bpp) { return bpp - 7 + 'a'; }
|
static inline char encode_bpp(int bpp) { return bpp - 7 + 'a'; }
|
||||||
|
|
||||||
static __attribute__((unused)) int encode_set_reference(int cnt, unsigned* hash_arr, int bpp,
|
|
||||||
char* base62_str) {
|
|
||||||
int Mshift = encode_golomb_Mshift(cnt, bpp);
|
|
||||||
int bit_cnt = encode_golomb_size(cnt, Mshift);
|
|
||||||
|
|
||||||
char bit_arr[bit_cnt];
|
|
||||||
|
|
||||||
*base62_str++ = encode_bpp(bpp);
|
|
||||||
*base62_str++ = encode_bpp(Mshift);
|
|
||||||
|
|
||||||
// hash_arr -> delta_arr
|
|
||||||
encode_delta(cnt, hash_arr);
|
|
||||||
bit_cnt = encode_golomb(cnt, hash_arr, Mshift, bit_arr);
|
|
||||||
assert(bit_cnt >= 0);
|
|
||||||
|
|
||||||
size_t base62_len = encode_base62(bit_cnt, bit_arr, base62_str);
|
|
||||||
assert(base62_len > 0);
|
|
||||||
|
|
||||||
return 2 + base62_len;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct encode_writer {
|
struct encode_writer {
|
||||||
uint64_t bits;
|
uint64_t bits;
|
||||||
unsigned filled;
|
unsigned filled;
|
||||||
@@ -333,12 +230,14 @@ struct encode_writer {
|
|||||||
|
|
||||||
static inline void encode_writer_digit(struct encode_writer* writer, unsigned value) {
|
static inline void encode_writer_digit(struct encode_writer* writer, unsigned value) {
|
||||||
assert(value < 62);
|
assert(value < 62);
|
||||||
if (value < 10)
|
|
||||||
|
if (value < 10) {
|
||||||
*writer->output++ = (char)('0' + value);
|
*writer->output++ = (char)('0' + value);
|
||||||
else if (value < 36)
|
} else if (value < 36) {
|
||||||
*writer->output++ = (char)('a' + value - 10);
|
*writer->output++ = (char)('a' + value - 10);
|
||||||
else
|
} else {
|
||||||
*writer->output++ = (char)('A' + value - 36);
|
*writer->output++ = (char)('A' + value - 36);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void encode_writer_flush(struct encode_writer* writer) {
|
static inline void encode_writer_flush(struct encode_writer* writer) {
|
||||||
@@ -368,14 +267,19 @@ static inline void encode_writer_zeros(struct encode_writer* writer, unsigned co
|
|||||||
unsigned take = count > 56 ? 56 : count;
|
unsigned take = count > 56 ? 56 : count;
|
||||||
writer->filled += take;
|
writer->filled += take;
|
||||||
count -= take;
|
count -= take;
|
||||||
|
|
||||||
encode_writer_flush(writer);
|
encode_writer_flush(writer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void encode_writer_put(struct encode_writer* writer, uint64_t value, unsigned width) {
|
static inline void encode_writer_put(struct encode_writer* writer, uint64_t value, unsigned width) {
|
||||||
writer->bits |= value << writer->filled;
|
writer->bits |= value << writer->filled;
|
||||||
writer->filled += width;
|
writer->filled += width;
|
||||||
encode_writer_flush(writer);
|
encode_writer_flush(writer);
|
||||||
|
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int encode_set(int cnt, const unsigned* hash_arr, int bpp, char* base62_str) {
|
static int encode_set(int cnt, const unsigned* hash_arr, int bpp, char* base62_str) {
|
||||||
@@ -404,7 +308,9 @@ static int encode_set(int cnt, const unsigned* hash_arr, int bpp, char* base62_s
|
|||||||
if (writer.escaped) value |= writer.pending_high;
|
if (writer.escaped) value |= writer.pending_high;
|
||||||
encode_writer_digit(&writer, value);
|
encode_writer_digit(&writer, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
*writer.output = '\0';
|
*writer.output = '\0';
|
||||||
|
|
||||||
return (int)(writer.output - start);
|
return (int)(writer.output - start);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -597,107 +503,8 @@ static char* put4bits(int c, char* bit_pt) {
|
|||||||
return bit_pt;
|
return bit_pt;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Main base62 decoding routine: unpack base62 string into bit_pt[].
|
// Decode base62 and Golomb-Rice in one pass. Base62 is LSB-first; a Z escape contributes 10 stream
|
||||||
static int decode_base62(const char* base62_str, char* bit_pt) {
|
// bits.
|
||||||
char* bit_start = bit_pt;
|
|
||||||
|
|
||||||
unsigned num6b = char_to_num[(unsigned char)*base62_str++]; // pending 6-bit number
|
|
||||||
while (num6b != 0xff) {
|
|
||||||
if (num6b == 0xee) return -1;
|
|
||||||
|
|
||||||
if (num6b < 61) {
|
|
||||||
bit_pt = put6bits(num6b, bit_pt);
|
|
||||||
} else {
|
|
||||||
assert(num6b == 61);
|
|
||||||
// 61 62 63 cases
|
|
||||||
|
|
||||||
unsigned mask = (1u << 4) | (1u << 5); // high bits mask
|
|
||||||
unsigned num4b = char_to_num[(unsigned char)*base62_str++];
|
|
||||||
if (num4b == 0xff) return -2;
|
|
||||||
if (num4b == 0xee) return -3;
|
|
||||||
|
|
||||||
unsigned num2b = num4b & mask; // high bits
|
|
||||||
num4b &= ~mask; // low bits
|
|
||||||
assert(num2b != mask); // not both bits set
|
|
||||||
|
|
||||||
bit_pt = put6bits(61 + (num2b >> 4), bit_pt); // 61 + (0|1|2) in high bits
|
|
||||||
bit_pt = put4bits(num4b, bit_pt);
|
|
||||||
}
|
|
||||||
|
|
||||||
num6b = char_to_num[(unsigned char)*base62_str++];
|
|
||||||
}
|
|
||||||
|
|
||||||
return bit_pt - bit_start;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Main golomb decoding routine: unpackage bits into values.
|
|
||||||
static int decode_golomb(int bit_cnt, const char* bit_pt, int Mshift, unsigned* golomb_pt) {
|
|
||||||
unsigned* golomb_start = golomb_pt;
|
|
||||||
|
|
||||||
// next value
|
|
||||||
while (bit_cnt > 0) {
|
|
||||||
// first part
|
|
||||||
unsigned q = 0;
|
|
||||||
char bit = 0;
|
|
||||||
while (bit_cnt > 0) {
|
|
||||||
bit_cnt--;
|
|
||||||
bit = *bit_pt++;
|
|
||||||
|
|
||||||
if (bit == 0) {
|
|
||||||
q++;
|
|
||||||
} else {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// trailing zero bits in the input are okay
|
|
||||||
if (bit_cnt == 0 && bit == 0) {
|
|
||||||
// up to 5 bits can be used to complete last character
|
|
||||||
if (q > 5) {
|
|
||||||
return -10;
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// otherwise, incomplete value is not okay
|
|
||||||
if (bit_cnt < Mshift) {
|
|
||||||
return -11;
|
|
||||||
}
|
|
||||||
|
|
||||||
// second part
|
|
||||||
unsigned r = 0;
|
|
||||||
int i;
|
|
||||||
for (i = 0; i < Mshift; i++) {
|
|
||||||
bit_cnt--;
|
|
||||||
if (*bit_pt++) {
|
|
||||||
r |= (1u << i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// the value
|
|
||||||
*golomb_pt++ = (q << Mshift) | r;
|
|
||||||
}
|
|
||||||
|
|
||||||
return golomb_pt - golomb_start;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void decode_delta(int cnt, unsigned* delta_pt) {
|
|
||||||
assert(cnt > 0);
|
|
||||||
unsigned* delta_end = delta_pt + cnt;
|
|
||||||
unsigned prev = *delta_pt++;
|
|
||||||
|
|
||||||
while (delta_pt < delta_end) {
|
|
||||||
*delta_pt += prev;
|
|
||||||
prev = *delta_pt++;
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Decode base62 and Golomb-Rice in one pass. Keeping bits in a register avoids
|
|
||||||
// materializing the intermediate one-byte-per-bit VLA used by the reference
|
|
||||||
// decoder. Base62 is LSB-first; a Z escape contributes 10 stream bits.
|
|
||||||
static inline int decode_chunk(const unsigned char** input, uint64_t* chunk, unsigned* width) {
|
static inline int decode_chunk(const unsigned char** input, uint64_t* chunk, unsigned* width) {
|
||||||
unsigned value = char_to_num[*(*input)++];
|
unsigned value = char_to_num[*(*input)++];
|
||||||
|
|
||||||
@@ -718,6 +525,7 @@ static inline int decode_chunk(const unsigned char** input, uint64_t* chunk, uns
|
|||||||
|
|
||||||
*chunk = (61u + (high >> 4)) | ((uint64_t)(escaped & 0x0fu) << 6);
|
*chunk = (61u + (high >> 4)) | ((uint64_t)(escaped & 0x0fu) << 6);
|
||||||
*width = 10;
|
*width = 10;
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -738,8 +546,10 @@ static int decode_set(const struct set_meta* meta, unsigned* hash_arr) {
|
|||||||
uint64_t chunk;
|
uint64_t chunk;
|
||||||
unsigned width;
|
unsigned width;
|
||||||
int rc = decode_chunk(&input, &chunk, &width);
|
int rc = decode_chunk(&input, &chunk, &width);
|
||||||
|
|
||||||
if (rc < 0) return rc;
|
if (rc < 0) return rc;
|
||||||
if (rc == 0) return q <= 5 ? count : -10;
|
if (rc == 0) return q <= 5 ? count : -10;
|
||||||
|
|
||||||
bits = chunk;
|
bits = chunk;
|
||||||
filled = width;
|
filled = width;
|
||||||
}
|
}
|
||||||
@@ -785,23 +595,7 @@ static int decode_set(const struct set_meta* meta, unsigned* hash_arr) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Kept as a readable reference for differential SELF_TEST/debug builds.
|
// Bounded decoded-set cache: bucketed lookup plus O(1) LRU updates.
|
||||||
static __attribute__((unused)) int decode_set_reference(const struct set_meta* meta,
|
|
||||||
unsigned* hash_arr) {
|
|
||||||
char bit_arr[meta->bit_capacity];
|
|
||||||
|
|
||||||
int bit_cnt = decode_base62(meta->payload, bit_arr);
|
|
||||||
if (bit_cnt < 0) return bit_cnt;
|
|
||||||
|
|
||||||
int cnt = decode_golomb(bit_cnt, bit_arr, meta->Mshift, hash_arr);
|
|
||||||
if (cnt <= 0) return cnt < 0 ? cnt : -12;
|
|
||||||
|
|
||||||
decode_delta(cnt, hash_arr);
|
|
||||||
return cnt;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Bounded decoded-set cache: bucketed lookup plus O(1) LRU updates. The old
|
|
||||||
// flat array searched and memmoved up to 512 entries on every non-front hit.
|
|
||||||
static int downsample_set(int cnt, const unsigned* hash_pt, unsigned* ds_pt, int bpp);
|
static int downsample_set(int cnt, const unsigned* hash_pt, unsigned* ds_pt, int bpp);
|
||||||
|
|
||||||
static int cache_decode_set(struct set_meta* meta, int target_bpp, const unsigned** hash_pt,
|
static int cache_decode_set(struct set_meta* meta, int target_bpp, const unsigned** hash_pt,
|
||||||
@@ -850,6 +644,7 @@ static int cache_decode_set(struct set_meta* meta, int target_bpp, const unsigne
|
|||||||
}
|
}
|
||||||
|
|
||||||
*hash_pt = ent->hash_arr;
|
*hash_pt = ent->hash_arr;
|
||||||
|
|
||||||
return ent->cnt;
|
return ent->cnt;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -857,10 +652,9 @@ static int cache_decode_set(struct set_meta* meta, int target_bpp, const unsigne
|
|||||||
|
|
||||||
int len = (int)meta->len;
|
int len = (int)meta->len;
|
||||||
int capacity = meta->value_capacity;
|
int capacity = meta->value_capacity;
|
||||||
struct cache_ent* ent =
|
struct cache_ent* ent = xmalloc(sizeof(*ent) + (size_t)(capacity) * sizeof(unsigned) + len + 1);
|
||||||
xmalloc(sizeof(*ent) + (size_t)(capacity + SENTINELS) * sizeof(unsigned) + len + 1);
|
|
||||||
ent->hash_arr = (unsigned*)(ent + 1);
|
ent->hash_arr = (unsigned*)(ent + 1);
|
||||||
ent->str = (char*)(ent->hash_arr + capacity + SENTINELS);
|
ent->str = (char*)(ent->hash_arr + capacity);
|
||||||
|
|
||||||
int cnt = decode_set(meta, ent->hash_arr);
|
int cnt = decode_set(meta, ent->hash_arr);
|
||||||
if (cnt <= 0) {
|
if (cnt <= 0) {
|
||||||
@@ -885,7 +679,6 @@ static int cache_decode_set(struct set_meta* meta, int target_bpp, const unsigne
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < SENTINELS; ++i) ent->hash_arr[cnt + i] = ~0u;
|
|
||||||
memcpy(ent->str, meta->str, (size_t)len + 1);
|
memcpy(ent->str, meta->str, (size_t)len + 1);
|
||||||
ent->fingerprint = fp;
|
ent->fingerprint = fp;
|
||||||
ent->len = len;
|
ent->len = len;
|
||||||
@@ -916,13 +709,15 @@ static int cache_decode_set(struct set_meta* meta, int target_bpp, const unsigne
|
|||||||
buckets[cache_id][bucket] = ent;
|
buckets[cache_id][bucket] = ent;
|
||||||
ent->newer = NULL;
|
ent->newer = NULL;
|
||||||
ent->older = newest[cache_id];
|
ent->older = newest[cache_id];
|
||||||
if (newest[cache_id])
|
if (newest[cache_id]) {
|
||||||
newest[cache_id]->newer = ent;
|
newest[cache_id]->newer = ent;
|
||||||
else
|
} else {
|
||||||
oldest[cache_id] = ent;
|
oldest[cache_id] = ent;
|
||||||
|
}
|
||||||
newest[cache_id] = ent;
|
newest[cache_id] = ent;
|
||||||
|
|
||||||
*hash_pt = ent->hash_arr;
|
*hash_pt = ent->hash_arr;
|
||||||
|
|
||||||
return cnt;
|
return cnt;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1037,6 +832,7 @@ static int sorted_subset(const unsigned* small, size_t small_count, const unsign
|
|||||||
if (large == large_end || *large != value) return 0;
|
if (large == large_end || *large != value) return 0;
|
||||||
++large;
|
++large;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1046,6 +842,7 @@ static int sorted_subset(const unsigned* small, size_t small_count, const unsign
|
|||||||
if (large == large_end || *large != value) return 0;
|
if (large == large_end || *large != value) return 0;
|
||||||
++large;
|
++large;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user