32 static void rs_block_sig_init(
rs_block_sig_t *sig, rs_weak_sum_t weak_sum,
33 rs_strong_sum_t *strong_sum,
int strong_len)
37 memcpy(sig->
strong_sum, strong_sum, strong_len);
40 static inline unsigned rs_block_sig_hash(
const rs_block_sig_t *sig)
53 rs_weak_sum_t weak_sum,
54 rs_strong_sum_t *strong_sum,
const void *buf,
57 rs_block_sig_init(&match->block_sig, weak_sum, strong_sum,
59 match->signature = sig;
69 #ifndef HASHTABLE_NSTATS
72 rs_signature_calc_strong_sum(match->signature, match->buf, match->len,
82 #define HASHTABLE_NMIX32
84 #define ENTRY rs_block_sig
85 #define MATCH rs_block_match
86 #define NAME hashtable
96 sizeof(rs_weak_sum_t)-
97 1) /
sizeof(rs_weak_sum_t)) *
98 sizeof(rs_weak_sum_t);
106 block_idx * rs_block_sig_size(sig));
113 return ((
char *)block_sig -
114 (
char *)sig->
block_sigs) / rs_block_sig_size(sig);
118 size_t *block_len,
size_t *strong_len)
120 size_t rec_block_len;
122 size_t min_strong_len;
124 size_t max_strong_len;
131 max_strong_len = RS_BLAKE2_SUM_LENGTH;
135 max_strong_len = RS_MD4_SUM_LENGTH;
138 rs_error(
"invalid magic %#x", *magic);
149 old_fsize <= 256 * 256 ? 256 : rs_long_sqrt(old_fsize) & ~127;
152 *block_len = rec_block_len;
167 2 + (rs_long_ln2(old_fsize + ((rs_long_t)1 << 24)) +
168 rs_long_ln2(old_fsize / *block_len + 1) + 7) / 8;
170 if (*strong_len == 0)
171 *strong_len = max_strong_len;
172 else if (*strong_len == -1)
173 *strong_len = min_strong_len;
174 else if (old_fsize >= 0 && *strong_len < min_strong_len) {
176 "strong_len=" FMT_SIZE
" smaller than recommended minimum "
177 FMT_SIZE
" for old_fsize=" FMT_LONG
" with block_len=" FMT_SIZE,
178 *strong_len, min_strong_len, old_fsize, *block_len);
179 }
else if (*strong_len > max_strong_len) {
180 rs_error(
"invalid strong_len=" FMT_SIZE
" for magic=%#x", *strong_len,
184 rs_sig_args_check(*magic, *block_len, *strong_len);
189 size_t block_len,
size_t strong_len,
205 sig->
size = (int)(sig_fsize < 12 ? 0 : (sig_fsize - 12) / (4 + strong_len));
208 rs_alloc(sig->
size * rs_block_sig_size(sig),
209 "signature->block_sigs");
213 #ifndef HASHTABLE_NSTATS
216 rs_signature_check(sig);
224 rs_bzero(sig,
sizeof(*sig));
228 rs_weak_sum_t weak_sum,
229 rs_strong_sum_t *strong_sum)
231 rs_signature_check(sig);
233 if (rs_signature_weaksum_kind(sig) == RS_ROLLSUM)
234 weak_sum =
mix32(weak_sum);
240 "signature->block_sigs");
247 rs_long_t rs_signature_find_match(
rs_signature_t *sig, rs_weak_sum_t weak_sum,
248 void const *buf,
size_t len)
253 rs_signature_check(sig);
254 rs_block_match_init(&m, sig, weak_sum, NULL, buf, len);
255 if ((b = hashtable_find(sig->
hashtable, &m))) {
256 return (rs_long_t)rs_block_sig_idx(sig, b) * sig->
block_len;
263 #ifndef HASHTABLE_NSTATS
267 "match statistics: signature[%ld searches, %ld (%.3f%%) matches, "
268 "%ld (%.3fx) weak sum compares, %ld (%.3f%%) strong sum compares, "
284 rs_signature_check(sig);
288 for (i = 0; i < sig->
count; i++) {
289 b = rs_block_sig_ptr(sig, i);
300 rs_signature_done(psums);
308 char strong_hex[RS_MAX_STRONG_SUM_LENGTH * 3];
311 "sumset info: magic=%#x, block_len=%d, block_num=%d", sums->
magic,
314 for (i = 0; i < sums->
count; i++) {
315 b = rs_block_sig_ptr(sums, i);
318 "sum %6d: weak=" FMT_WEAKSUM
", strong=%s", i, b->
weak_sum,