delete unused funcs
This commit is contained in:
@@ -14,7 +14,6 @@
|
||||
|
||||
#define CACHE_SIZE 512
|
||||
#define PIVOT_SIZE 486
|
||||
#define SENTINELS 0
|
||||
|
||||
struct set {
|
||||
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));
|
||||
|
||||
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.
|
||||
/*
|
||||
* Base62 routines - encode bits with alnum characters.
|
||||
@@ -260,69 +216,10 @@ static char* bits_to_char(int c, char* 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 __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 {
|
||||
uint64_t bits;
|
||||
unsigned filled;
|
||||
@@ -333,12 +230,14 @@ struct encode_writer {
|
||||
|
||||
static inline void encode_writer_digit(struct encode_writer* writer, unsigned value) {
|
||||
assert(value < 62);
|
||||
if (value < 10)
|
||||
|
||||
if (value < 10) {
|
||||
*writer->output++ = (char)('0' + value);
|
||||
else if (value < 36)
|
||||
} else if (value < 36) {
|
||||
*writer->output++ = (char)('a' + value - 10);
|
||||
else
|
||||
} else {
|
||||
*writer->output++ = (char)('A' + value - 36);
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
writer->filled += take;
|
||||
count -= take;
|
||||
|
||||
encode_writer_flush(writer);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static inline void encode_writer_put(struct encode_writer* writer, uint64_t value, unsigned width) {
|
||||
writer->bits |= value << writer->filled;
|
||||
writer->filled += width;
|
||||
encode_writer_flush(writer);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
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;
|
||||
encode_writer_digit(&writer, value);
|
||||
}
|
||||
|
||||
*writer.output = '\0';
|
||||
|
||||
return (int)(writer.output - start);
|
||||
}
|
||||
|
||||
@@ -597,107 +503,8 @@ static char* put4bits(int c, char* bit_pt) {
|
||||
return bit_pt;
|
||||
}
|
||||
|
||||
// Main base62 decoding routine: unpack base62 string into bit_pt[].
|
||||
static int decode_base62(const char* base62_str, char* bit_pt) {
|
||||
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.
|
||||
// Decode base62 and Golomb-Rice in one pass. 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) {
|
||||
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);
|
||||
*width = 10;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -738,8 +546,10 @@ static int decode_set(const struct set_meta* meta, unsigned* hash_arr) {
|
||||
uint64_t chunk;
|
||||
unsigned width;
|
||||
int rc = decode_chunk(&input, &chunk, &width);
|
||||
|
||||
if (rc < 0) return rc;
|
||||
if (rc == 0) return q <= 5 ? count : -10;
|
||||
|
||||
bits = chunk;
|
||||
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.
|
||||
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.
|
||||
// Bounded decoded-set cache: bucketed lookup plus O(1) LRU updates.
|
||||
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,
|
||||
@@ -850,6 +644,7 @@ static int cache_decode_set(struct set_meta* meta, int target_bpp, const unsigne
|
||||
}
|
||||
|
||||
*hash_pt = ent->hash_arr;
|
||||
|
||||
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 capacity = meta->value_capacity;
|
||||
struct cache_ent* ent =
|
||||
xmalloc(sizeof(*ent) + (size_t)(capacity + SENTINELS) * sizeof(unsigned) + len + 1);
|
||||
struct cache_ent* ent = xmalloc(sizeof(*ent) + (size_t)(capacity) * sizeof(unsigned) + len + 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);
|
||||
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);
|
||||
ent->fingerprint = fp;
|
||||
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;
|
||||
ent->newer = NULL;
|
||||
ent->older = newest[cache_id];
|
||||
if (newest[cache_id])
|
||||
if (newest[cache_id]) {
|
||||
newest[cache_id]->newer = ent;
|
||||
else
|
||||
} else {
|
||||
oldest[cache_id] = ent;
|
||||
}
|
||||
newest[cache_id] = ent;
|
||||
|
||||
*hash_pt = ent->hash_arr;
|
||||
|
||||
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;
|
||||
++large;
|
||||
}
|
||||
|
||||
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;
|
||||
++large;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user