/* * 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"); }
/* * 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); } }
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; }
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); }
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; }