#include <string.h> /* size_t */
#include <limb/int.h>
#include "rabin-tables.h"
#define BREAKMARK_VALUE 0x78
size_t
nextsplit(size_t min, size_t avg, const void *data, size_t dlen)
{
if (dlen <= min) return dlen;
u64 mask = (1 << (msb64(avg ) - 1)) - 1;
u64 lrg_mask = (1 << (msb64(avg / 2) - 1)) - 1;
u64 fp = 0;
int i = min, wpos = -1;
int m = 0;
const u8 *sce = data;
u8 window[RABIN_WINDOW_SIZE] = { 0 };
while (i < dlen) {
u8 om;
u64 x;
if (++wpos >= sizeof(window))
wpos = 0;
om = window[wpos];
window[wpos] = sce[i - 1];
fp ^= rabin_tables.U[om];
x = fp >> 55;
fp <<= 8;
fp |= sce[i - 1];
fp ^= rabin_tables.T[x];
if (i >= min) {
if ((fp & lrg_mask) == BREAKMARK_VALUE) {
if ((fp & mask) == BREAKMARK_VALUE)
return i;
m = i;
}
}
++i;
}
if (m)
return m;
return i;
}