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);
147 rec_block_len = old_fsize <= 256 * 256 ? 256 : rs_long_sqrt(old_fsize);
150 *block_len = rec_block_len;
165 2 + (rs_long_ln2(old_fsize + ((rs_long_t)1 << 24)) +
166 rs_long_ln2(old_fsize / *block_len + 1) + 7) / 8;
168 if (*strong_len == 0)
169 *strong_len = max_strong_len;
170 else if (*strong_len == -1)
171 *strong_len = min_strong_len;
172 else if (old_fsize >= 0 && *strong_len < min_strong_len) {
174 "strong_len=" FMT_SIZE
" smaller than recommended minimum "
175 FMT_SIZE
" for old_fsize=" FMT_LONG
" with block_len=" FMT_SIZE,
176 *strong_len, min_strong_len, old_fsize, *block_len);
177 }
else if (*strong_len > max_strong_len) {
178 rs_error(
"invalid strong_len=" FMT_SIZE
" for magic=%#x", *strong_len,
182 rs_sig_args_check(*magic, *block_len, *strong_len);
187 size_t block_len,
size_t strong_len,
203 sig->
size = (int)(sig_fsize < 12 ? 0 : (sig_fsize - 12) / (4 + strong_len));
206 rs_alloc(sig->
size * rs_block_sig_size(sig),
207 "signature->block_sigs");
211 #ifndef HASHTABLE_NSTATS
214 rs_signature_check(sig);
222 rs_bzero(sig,
sizeof(*sig));
226 rs_weak_sum_t weak_sum,
227 rs_strong_sum_t *strong_sum)
229 rs_signature_check(sig);
231 if (rs_signature_weaksum_kind(sig) == RS_ROLLSUM)
232 weak_sum =
mix32(weak_sum);
238 "signature->block_sigs");
245 rs_long_t rs_signature_find_match(
rs_signature_t *sig, rs_weak_sum_t weak_sum,
246 void const *buf,
size_t len)
251 rs_signature_check(sig);
252 rs_block_match_init(&m, sig, weak_sum, NULL, buf, len);
253 if ((b = hashtable_find(sig->
hashtable, &m))) {
254 return (rs_long_t)rs_block_sig_idx(sig, b) * sig->
block_len;
261 #ifndef HASHTABLE_NSTATS
265 "match statistics: signature[%ld searches, %ld (%.3f%%) matches, "
266 "%ld (%.3fx) weak sum compares, %ld (%.3f%%) strong sum compares, "
282 rs_signature_check(sig);
286 for (i = 0; i < sig->
count; i++) {
287 b = rs_block_sig_ptr(sig, i);
298 rs_signature_done(psums);
306 char strong_hex[RS_MAX_STRONG_SUM_LENGTH * 3];
309 "sumset info: magic=%#x, block_len=%d, block_num=%d", sums->
magic,
312 for (i = 0; i < sums->
count; i++) {
313 b = rs_block_sig_ptr(sums, i);
316 "sum %6d: weak=" FMT_WEAKSUM
", strong=%s", i, b->
weak_sum,