void fingerprint_cache_prefetch(int64_t id){
	switch(destor.index_category[1]){
		case INDEX_CATEGORY_PHYSICAL_LOCALITY:{
			struct containerMeta * cm = retrieve_container_meta_by_id(id);
			if (cm) {
				lru_cache_insert(lru_queue, cm, NULL, NULL);
			} else{
				WARNING("Error! The container %lld has not been written!", id);
				exit(1);
			}
			break;
		}
		case INDEX_CATEGORY_LOGICAL_LOCALITY:{
			GQueue* segments = prefetch_segments(id,
					destor.index_segment_prefech);
			VERBOSE("Dedup phase: prefetch %d segments into %d cache",
					g_queue_get_length(segments),
					destor.index_cache_size);
			struct segmentRecipe* sr;
			while ((sr = g_queue_pop_tail(segments))) {
				/* From tail to head */
				if (!lru_cache_hits(lru_queue, &sr->id,
						segment_recipe_check_id)) {
					lru_cache_insert(lru_queue, sr, NULL, NULL);
				} else {
					 /* Already in cache */
					free_segment_recipe(sr);
				}
			}
			g_queue_free(segments);
			break;
		}
	}
}
Beispiel #2
0
static void* lru_restore_thread(void *arg) {
	struct lruCache *cache;
	if (destor.simulation_level >= SIMULATION_RESTORE)
		cache = new_lru_cache(destor.restore_cache[1], free_container_meta,
				lookup_fingerprint_in_container_meta);
	else
		cache = new_lru_cache(destor.restore_cache[1], free_container,
				lookup_fingerprint_in_container);

	struct chunk* c;
	while ((c = sync_queue_pop(restore_recipe_queue))) {

		if (CHECK_CHUNK(c, CHUNK_FILE_START) || CHECK_CHUNK(c, CHUNK_FILE_END)) {
			sync_queue_push(restore_chunk_queue, c);
			continue;
		}

		TIMER_DECLARE(1);
		TIMER_BEGIN(1);

		if (destor.simulation_level >= SIMULATION_RESTORE) {
			struct containerMeta *cm = lru_cache_lookup(cache, &c->fp);
			if (!cm) {
				VERBOSE("Restore cache: container %lld is missed", c->id);
				cm = retrieve_container_meta_by_id(c->id);
				assert(lookup_fingerprint_in_container_meta(cm, &c->fp));
				lru_cache_insert(cache, cm, NULL, NULL);
				jcr.read_container_num++;
			}

			TIMER_END(1, jcr.read_chunk_time);
		} else {
			struct container *con = lru_cache_lookup(cache, &c->fp);
			if (!con) {
				VERBOSE("Restore cache: container %lld is missed", c->id);
				con = retrieve_container_by_id(c->id);
				lru_cache_insert(cache, con, NULL, NULL);
				jcr.read_container_num++;
			}
			struct chunk *rc = get_chunk_in_container(con, &c->fp);
			assert(rc);
			TIMER_END(1, jcr.read_chunk_time);
			sync_queue_push(restore_chunk_queue, rc);
		}

		free_chunk(c);
	}

	sync_queue_term(restore_chunk_queue);

	free_lru_cache(cache);

	return NULL;
}
Beispiel #3
0
/*
 * We assume a FIFO order of deleting backup, namely the oldest backup is deleted first.
 */
void do_delete(int jobid) {

	GHashTable *invalid_containers = trunc_manifest(jobid);

	init_index();
	init_recipe_store();

	/* Delete the invalid entries in the key-value store */
	if(destor.index_category[1] == INDEX_CATEGORY_PHYSICAL_LOCALITY){
		init_container_store();

		struct backupVersion* bv = open_backup_version(jobid);

		/* The entries pointing to Invalid Containers are invalid. */
		GHashTableIter iter;
		gpointer key, value;
		g_hash_table_iter_init(&iter, invalid_containers);
		while(g_hash_table_iter_next(&iter, &key, &value)){
			containerid id = *(containerid*)key;
			NOTICE("Reclaim container %lld", id);
			struct containerMeta* cm = retrieve_container_meta_by_id(id);

			container_meta_foreach(cm, delete_an_entry, &id);

			free_container_meta(cm);
		}

		bv->deleted = 1;
		update_backup_version(bv);
		free_backup_version(bv);

		close_container_store();
	}else if(destor.index_category[1] == INDEX_CATEGORY_LOGICAL_LOCALITY){
		/* Ideally, the entries pointing to segments in backup versions of a 'bv_num' less than 'jobid' are invalid. */
		/* (For simplicity) Since a FIFO order is given, we only need to remove the IDs exactly matched 'bv_num'. */
		struct backupVersion* bv = open_backup_version(jobid);

		struct segmentRecipe* sr;
		while((sr=read_next_segment(bv))){
			segment_recipe_foreach(sr, delete_an_entry, &sr->id);
		}

		bv->deleted = 1;
		update_backup_version(bv);
		free_backup_version(bv);

	}else{
		WARNING("Invalid index type");
		exit(1);
	}

	close_recipe_store();
	close_index();

	char logfile[] = "delete.log";
	FILE *fp = fopen(logfile, "a");
	/*
	 * ID of the job we delete,
	 * number of live containers,
	 * memory footprint
	 */
	fprintf(fp, "%d %d %d\n",
			jobid,
			destor.live_container_num,
			destor.index_memory_footprint);

	fclose(fp);

	/* record the IDs of invalid containers */
	sds didfilepath = sdsdup(destor.working_directory);
	char s[128];
	sprintf(s, "recipes/delete_%d.id", jobid);
	didfilepath = sdscat(didfilepath, s);

	FILE*  didfile = fopen(didfilepath, "w");
	if(didfile){
		GHashTableIter iter;
		gpointer key, value;
		g_hash_table_iter_init(&iter, invalid_containers);
		while(g_hash_table_iter_next(&iter, &key, &value)){
			containerid id = *(containerid*)key;
			fprintf(didfile, "%lld\n", id);
		}

		fclose(didfile);
	}


	g_hash_table_destroy(invalid_containers);
}