/* Create a chunk boundary */
ssize_t zck_end_chunk(zckCtx *zck)
__attribute__ ((warn_unused_result));
-
+/* Create the database for uthash if not present (done automatically by read */
+bool zck_generate_hashdb(zckCtx *zck);
/*******************************************************************
* Common functions for finishing a zchunk file
__attribute__ ((warn_unused_result));
/* Reset failed chunks to become missing */
void zck_reset_failed_chunks(zckCtx *zck);
-
+/* Find chunks from a source */
+bool zck_find_matching_chunks(zckCtx *src, zckCtx *tgt);
/*******************************************************************
* The functions should be all you need to read and write a zchunk
return true;
}
+bool PUBLIC zck_find_matching_chunks(zckCtx *src, zckCtx *tgt) {
+
+ if (!src || !tgt)
+ return false;
+
+ zckIndex *src_info = &(src->index);
+ zckIndex *tgt_info = &(tgt->index);
+ zckChunk *tgt_idx = tgt_info->first;
+ while(tgt_idx) {
+ zckChunk *f = NULL;
+ /*
+ * This function can be called multiple time with different
+ * zckCtx *src, and the resulting tgt will have a list with
+ * chunks from different sources. Check first if comparison ran
+ * for the chunk and it was already set as valid
+ */
+ if (tgt_idx->valid)
+ continue;
+ /*
+ * Compare digest for compressed data if the same compressor
+ * was iused
+ */
+ if (src->comp.type == tgt->comp.type) {
+ HASH_FIND(hh, src_info->ht, tgt_idx->digest, tgt_idx->digest_size, f);
+ } else if (src->has_uncompressed_source && tgt->has_uncompressed_source) {
+ HASH_FIND(hhuncomp, src_info->htuncomp, tgt_idx->digest_uncompressed, tgt_idx->digest_size, f);
+ } else {
+
+ }
+ if(f && f->length == tgt_idx->length) {
+ tgt_idx->valid = 1;
+ tgt_idx->src = f;
+ } else {
+ tgt_idx->src = tgt_idx;
+ }
+ tgt_idx = tgt_idx->next;
+ }
+
+ return true;
+}
+
ssize_t PUBLIC zck_dl_get_bytes_downloaded(zckDL *dl) {
ALLOCD_INT(NULL, dl);
return;
HASH_CLEAR(hh, index->ht);
+ HASH_CLEAR(hhuncomp, index->htuncomp);
if(index->first) {
zckChunk *next;
zckChunk *tmp=index->first;
idx->valid = 0;
return;
}
+
+bool PUBLIC zck_generate_hashdb(zckCtx *zck) {
+ if (zck->index.ht || zck->index.htuncomp) {
+ zck_log(ZCK_LOG_ERROR, "Hash DB already present, it could not be created");
+ return false;
+ }
+
+ for(zckChunk *idx = zck->index.first; idx; idx=idx->next) {
+ zckChunk *tmp = NULL;
+ HASH_FIND(hh, zck->index.ht, idx->digest, idx->digest_size, tmp);
+ if(!tmp)
+ HASH_ADD_KEYPTR(hh, zck->index.ht, idx->digest, idx->digest_size,
+ idx);
+ /*
+ * Do the same if there is uncompressed digest
+ */
+ if (zck->has_uncompressed_source && idx->digest_uncompressed) {
+ HASH_FIND(hhuncomp, zck->index.htuncomp, idx->digest_uncompressed, idx->digest_size, tmp);
+ if(!tmp)
+ HASH_ADD_KEYPTR(hhuncomp, zck->index.htuncomp, idx->digest_uncompressed, idx->digest_size,
+ idx);
+ }
+ }
+
+ return true;
+}