Beispiel #1
0
/*
 * Close the least recently used window. You should check to see if
 * the file descriptors need closing from time to time.
 */
static int git_mwindow_close_lru(git_mwindow_file *mwf)
{
	unsigned int i;
	git_mwindow *lru_w = NULL, *lru_l = NULL;

	/* FIMXE: Does this give us any advantage? */
	if(mwf->windows)
		git_mwindow_scan_lru(mwf, &lru_w, &lru_l);

	for (i = 0; i < ctl.windowfiles.length; ++i) {
		git_mwindow_scan_lru(git_vector_get(&ctl.windowfiles, i), &lru_w, &lru_l);
	}

	if (lru_w) {
		git_mwindow_close(&lru_w);
		ctl.mapped -= lru_w->window_map.len;
		git_futils_mmap_free(&lru_w->window_map);

		if (lru_l)
			lru_l->next = lru_w->next;
		else
			mwf->windows = lru_w->next;

		free(lru_w);
		ctl.open_windows--;

		return GIT_SUCCESS;
	}

	return git__throw(GIT_ERROR, "Failed to close memory window. Couln't find LRU");
}
Beispiel #2
0
/*
 * Free all the windows in a sequence, typically because we're done
 * with the file
 */
void git_mwindow_free_all(git_mwindow_file *mwf)
{
	unsigned int i;
	/*
	 * Remove these windows from the global list
	 */
	for (i = 0; i < ctl.windowfiles.length; ++i){
		if (git_vector_get(&ctl.windowfiles, i) == mwf) {
			git_vector_remove(&ctl.windowfiles, i);
			break;
		}
	}

	if (ctl.windowfiles.length == 0) {
		git_vector_free(&ctl.windowfiles);
		ctl.windowfiles.contents = NULL;
	}

	while (mwf->windows) {
		git_mwindow *w = mwf->windows;
		assert(w->inuse_cnt == 0);

		ctl.mapped -= w->window_map.len;
		ctl.open_windows--;

		git_futils_mmap_free(&w->window_map);

		mwf->windows = w->next;
		free(w);
	}
}
Beispiel #3
0
void git_diff_file_content__unload(git_diff_file_content *fc)
{
	if ((fc->flags & GIT_DIFF_FLAG__LOADED) == 0)
		return;

	if (fc->flags & GIT_DIFF_FLAG__FREE_DATA) {
		git__free(fc->map.data);
		fc->map.data = "";
		fc->map.len  = 0;
		fc->flags &= ~GIT_DIFF_FLAG__FREE_DATA;
	}
	else if (fc->flags & GIT_DIFF_FLAG__UNMAP_DATA) {
		git_futils_mmap_free(&fc->map);
		fc->map.data = "";
		fc->map.len  = 0;
		fc->flags &= ~GIT_DIFF_FLAG__UNMAP_DATA;
	}

	if (fc->flags & GIT_DIFF_FLAG__FREE_BLOB) {
		git_blob_free((git_blob *)fc->blob);
		fc->blob = NULL;
		fc->flags &= ~GIT_DIFF_FLAG__FREE_BLOB;
	}

	fc->flags &= ~GIT_DIFF_FLAG__LOADED;
}
Beispiel #4
0
static void loose_backend__readstream_free(git_odb_stream *_stream)
{
	loose_readstream *stream = (loose_readstream *)_stream;

	git_futils_mmap_free(&stream->map);
	git_zstream_free(&stream->zstream);
	git__free(stream);
}
Beispiel #5
0
static int loose_backend__readstream(
	git_odb_stream **stream_out,
	size_t *len_out,
	git_otype *type_out,
	git_odb_backend *_backend,
	const git_oid *oid)
{
	loose_backend *backend;
	loose_readstream *stream = NULL;
	git_hash_ctx *hash_ctx = NULL;
	git_buf object_path = GIT_BUF_INIT;
	obj_hdr hdr;
	int error = 0;

	assert(stream_out && len_out && type_out && _backend && oid);

	backend = (loose_backend *)_backend;
	*stream_out = NULL;
	*len_out = 0;
	*type_out = GIT_OBJ_BAD;

	if (locate_object(&object_path, backend, oid) < 0) {
		error = git_odb__error_notfound("no matching loose object",
			oid, GIT_OID_HEXSZ);
		goto done;
	}

	stream = git__calloc(1, sizeof(loose_readstream));
	GITERR_CHECK_ALLOC(stream);

	hash_ctx = git__malloc(sizeof(git_hash_ctx));
	GITERR_CHECK_ALLOC(hash_ctx);

	if ((error = git_hash_ctx_init(hash_ctx)) < 0 ||
		(error = git_futils_mmap_ro_file(&stream->map, object_path.ptr)) < 0 ||
		(error = git_zstream_init(&stream->zstream, GIT_ZSTREAM_INFLATE)) < 0)
		goto done;

	/* check for a packlike loose object */
	if (!is_zlib_compressed_data(stream->map.data, stream->map.len))
		error = loose_backend__readstream_packlike(&hdr, stream);
	else
		error = loose_backend__readstream_standard(&hdr, stream);

	if (error < 0)
		goto done;

	stream->stream.backend = _backend;
	stream->stream.hash_ctx = hash_ctx;
	stream->stream.read = &loose_backend__readstream_read;
	stream->stream.free = &loose_backend__readstream_free;

	*stream_out = (git_odb_stream *)stream;
	*len_out = hdr.size;
	*type_out = hdr.type;

done:
	if (error < 0) {
		git_futils_mmap_free(&stream->map);
		git_zstream_free(&stream->zstream);
		git_hash_ctx_cleanup(hash_ctx);
		git__free(hash_ctx);
		git__free(stream);
	}

	git_buf_dispose(&object_path);
	return error;
}