Compute and compare Mean sketch cksum to improve similarity comparison

Fix optflags settings in Makefile
Small optimization in zero RLE encoder to avoid scanning during lookahead
Some minor fixes
This commit is contained in:
Moinak Ghosh 2012-08-09 23:57:24 +05:30
parent 400d0bfa72
commit f2ffcad2fd
4 changed files with 34 additions and 20 deletions

View file

@ -64,19 +64,22 @@ CPPFLAGS = -I. -I./lzma -I./lzfx -I./lz4 -I./rabin -I./bsdiff -D_7ZIP_ST -DNODEF
-DFILE_OFFSET_BITS=64 -D_REENTRANT -D__USE_SSE_INTRIN__ -D_LZMA_PROB32 -DFILE_OFFSET_BITS=64 -D_REENTRANT -D__USE_SSE_INTRIN__ -D_LZMA_PROB32
VEC_FLAGS = -ftree-vectorize VEC_FLAGS = -ftree-vectorize
LOOP_OPTFLAGS = $(VEC_FLAGS) -floop-interchange -floop-block LOOP_OPTFLAGS = $(VEC_FLAGS) -floop-interchange -floop-block
GEN_OPT = -O3
RABIN_OPT = -O2
LDLIBS = -ldl -lbz2 $(ZLIB_DIR) -lz -lm LDLIBS = -ldl -lbz2 $(ZLIB_DIR) -lz -lm
ifdef DEBUG ifdef DEBUG
LINK = g++ -m64 -pthread -msse3 LINK = g++ -m64 -pthread -msse3
COMPILE = gcc -m64 -O -g -msse3 -c COMPILE = gcc -m64 -g -msse3 -c
COMPILE_cpp = g++ -m64 -O -g -msse3 -c COMPILE_cpp = g++ -m64 -g -msse3 -c
VEC_FLAGS = VEC_FLAGS =
LOOP_OPTFLAGS =
GEN_OPT = -O
RABIN_OPT = -O
ifdef DEBUG_NO_SLAB ifdef DEBUG_NO_SLAB
CPPFLAGS += -DDEBUG_NO_SLAB CPPFLAGS += -DDEBUG_NO_SLAB
endif endif
else else
GEN_OPT = -O3
RABIN_OPT = -O2
LINK = g++ -m64 -pthread -msse3 LINK = g++ -m64 -pthread -msse3
COMPILE = gcc -m64 -msse3 -c COMPILE = gcc -m64 -msse3 -c
COMPILE_cpp = g++ -m64 -msse3 -c COMPILE_cpp = g++ -m64 -msse3 -c

View file

@ -47,7 +47,7 @@ zero_rle_encode(const void *const ibuf, const unsigned int ilen,
*((unsigned short *)(ob + pos2)) = htons(count); *((unsigned short *)(ob + pos2)) = htons(count);
pos2 += 2; pos2 += 2;
} else { } else {
unsigned int pos3, pos4, cnt, state; unsigned int pos3, pos4, state;
pos3 = pos2; pos3 = pos2;
pos2 += 2; pos2 += 2;
if (pos2 > *olen) break; if (pos2 > *olen) break;
@ -56,12 +56,12 @@ zero_rle_encode(const void *const ibuf, const unsigned int ilen,
for (;pos1<ilen && pos2<*olen && count<COUNT_MAX;) { for (;pos1<ilen && pos2<*olen && count<COUNT_MAX;) {
if (ib[pos1] != 0) state = 0; if (ib[pos1] != 0) state = 0;
if (ib[pos1] == 0 && !state) { if (ib[pos1] == 0 && !state) {
cnt = 0;
pos4 = pos1;
state = 1; state = 1;
// Lookahead if there are at least 4 consecutive zeroes // Lookahead if there are at least 4 consecutive zeroes
for (;pos4<ilen && ib[pos4] == 0; pos4++) cnt++; if (ilen > 3) {
if (cnt >= 4) break; pos4 = *((unsigned int *)(ib+pos1));
if (!pos4) break;
}
} }
ob[pos2++] = ib[pos1++]; ob[pos2++] = ib[pos1++];
count++; count++;

View file

@ -297,7 +297,6 @@ rabin_dedup(rabin_context_t *ctx, uchar_t *buf, ssize_t *size, ssize_t offset, s
length >= rabin_polynomial_max_block_size) { length >= rabin_polynomial_max_block_size) {
last_offset = i+1; last_offset = i+1;
length = 0; length = 0;
j = 0;
} }
} }
@ -342,7 +341,7 @@ rabin_dedup(rabin_context_t *ctx, uchar_t *buf, ssize_t *size, ssize_t offset, s
splits = (uint32_t *)(&fplist[fpos[1]]); splits = (uint32_t *)(&fplist[fpos[1]]);
#if BYTE_ORDER == BIG_ENDIAN #if BYTE_ORDER == BIG_ENDIAN
splits[0]++; splits[0]++;
splits[0] += cur_roll_checksum & ctx->fp_mask; splits[1] += cur_roll_checksum & ctx->fp_mask;
#else #else
splits[1]++; splits[1]++;
splits[0] += cur_roll_checksum & ctx->fp_mask; splits[0] += cur_roll_checksum & ctx->fp_mask;
@ -362,6 +361,7 @@ rabin_dedup(rabin_context_t *ctx, uchar_t *buf, ssize_t *size, ssize_t offset, s
memset(fplist, 0, fplist_sz); memset(fplist, 0, fplist_sz);
fpos[0] = 0; fpos[0] = 0;
len1 = 0; len1 = 0;
j++;
} }
/* /*
* Window pos has to rotate from 0 .. RAB_POLYNOMIAL_WIN_SIZE-1 * Window pos has to rotate from 0 .. RAB_POLYNOMIAL_WIN_SIZE-1
@ -382,6 +382,7 @@ rabin_dedup(rabin_context_t *ctx, uchar_t *buf, ssize_t *size, ssize_t offset, s
ctx->blocks[blknum].ref = 0; ctx->blocks[blknum].ref = 0;
ctx->blocks[blknum].similar = 0; ctx->blocks[blknum].similar = 0;
ctx->blocks[blknum].cksum_n_offset = cur_sketch; ctx->blocks[blknum].cksum_n_offset = cur_sketch;
ctx->blocks[blknum].mean_n_length = cur_sketch / j;
memset(fplist, 0, fplist_sz); memset(fplist, 0, fplist_sz);
fpos[0] = 0; fpos[0] = 0;
len1 = 0; len1 = 0;
@ -466,23 +467,33 @@ rabin_dedup(rabin_context_t *ctx, uchar_t *buf, ssize_t *size, ssize_t offset, s
} }
if (ctx->delta_flag) { if (ctx->delta_flag) {
uint64_t prev_mean;
prev_mean = 0;
prev_cksum = 0;
prev_length = 0;
for (blk = 0; blk < blknum; blk++) { for (blk = 0; blk < blknum; blk++) {
if (ctx->blocks[blk].similar) continue; if (ctx->blocks[blk].similar) continue;
/*
* Compare blocks for similarity.
* Note: Block list by now is sorted by length as well.
*/
if (blk > 0 && ctx->blocks[blk].ref == 0 && if (blk > 0 && ctx->blocks[blk].ref == 0 &&
ctx->blocks[blk].cksum_n_offset == prev_cksum && ctx->blocks[blk].cksum_n_offset == prev_cksum &&
ctx->blocks[blk].length - prev_length < 512 ctx->blocks[blk].length - prev_length < 512 &&
ctx->blocks[blk].mean_n_length == prev_mean
) { ) {
ctx->blocks[blk].index = prev_index; ctx->blocks[blk].index = prev_index;
ctx->blocks[blk].similar = SIMILAR_PARTIAL; ctx->blocks[blk].similar = SIMILAR_PARTIAL;
ctx->blocks[prev_blk].ref = 1; ctx->blocks[prev_blk].ref = 1;
matchlen += prev_length/2; matchlen += (prev_length>>1);
continue; continue;
} }
prev_offset = buf1 + ctx->blocks[blk].offset;
prev_cksum = ctx->blocks[blk].cksum_n_offset; prev_cksum = ctx->blocks[blk].cksum_n_offset;
prev_length = ctx->blocks[blk].length; prev_length = ctx->blocks[blk].length;
prev_index = ctx->blocks[blk].index; prev_index = ctx->blocks[blk].index;
prev_mean = ctx->blocks[blk].mean_n_length;
prev_blk = blk; prev_blk = blk;
} }
} }
@ -547,7 +558,7 @@ rabin_dedup(rabin_context_t *ctx, uchar_t *buf, ssize_t *size, ssize_t offset, s
prev_index = 0; prev_index = 0;
prev_length = 0; prev_length = 0;
ctx->blocks[pos].cksum_n_offset = be->offset; ctx->blocks[pos].cksum_n_offset = be->offset;
ctx->blocks[pos].new_length = be->length; ctx->blocks[pos].mean_n_length = be->length;
trans[blk] = pos; trans[blk] = pos;
if (be->similar == SIMILAR_EXACT) { if (be->similar == SIMILAR_EXACT) {
@ -589,12 +600,12 @@ rabin_dedup(rabin_context_t *ctx, uchar_t *buf, ssize_t *size, ssize_t offset, s
matchlen = ctx->real_chunksize - *size; matchlen = ctx->real_chunksize - *size;
bsz = bsdiff(old, ctx->blocks[j].length, new, bsz = bsdiff(old, ctx->blocks[j].length, new,
ctx->blocks[blk].new_length, ctx->cbuf + pos1, ctx->blocks[blk].mean_n_length, ctx->cbuf + pos1,
buf1 + *size, matchlen); buf1 + *size, matchlen);
if (bsz == 0) { if (bsz == 0) {
memcpy(ctx->cbuf + pos1, new, ctx->blocks[blk].new_length); memcpy(ctx->cbuf + pos1, new, ctx->blocks[blk].mean_n_length);
rabin_index[blk] = htonl(ctx->blocks[blk].new_length); rabin_index[blk] = htonl(ctx->blocks[blk].mean_n_length);
pos1 += ctx->blocks[blk].new_length; pos1 += ctx->blocks[blk].mean_n_length;
} else { } else {
rabin_index[blk] = htonl(trans[i] | rabin_index[blk] = htonl(trans[i] |
RABIN_INDEX_FLAG | SET_SIMILARITY_FLAG); RABIN_INDEX_FLAG | SET_SIMILARITY_FLAG);

View file

@ -133,9 +133,9 @@
typedef struct { typedef struct {
ssize_t offset; ssize_t offset;
uint64_t cksum_n_offset; // Dual purpose variable uint64_t cksum_n_offset; // Dual purpose variable
uint64_t mean_n_length; // Dual purpose variable
unsigned int index; unsigned int index;
unsigned int length; unsigned int length;
unsigned int new_length;
unsigned char ref, similar; unsigned char ref, similar;
} rabin_blockentry_t; } rabin_blockentry_t;