commit 1943de014775b966dbd5307f839f666123bb26f1 from: Stefan Sperling date: Fri Jun 22 08:46:10 2018 UTC add a commit cache as well commit - a9bf0c2c43fb5545d5929f63896d06d00281cdd7 commit + 1943de014775b966dbd5307f839f666123bb26f1 blob - 32c6146fa5cf6b5944f483716a79e0969bbc4e4b blob + df0f4ad3be5ed31bf13f8da8ca88aef61e9c0a7c --- include/got_object.h +++ include/got_object.h @@ -48,6 +48,8 @@ struct got_commit_object { char *committer; struct tm tm_committer; /* UTC */ char *logmsg; + + int refcnt; /* for internal use only */ }; /* A generic object. Used as a handle which holds an ID and an object type. */ blob - fbcf7b53c0bdfe9bb34535846550f44b0c38fbb1 blob + f25073b2d2020fd56df8a7a70de65ce9d55f481c --- lib/got_lib_repository.h +++ lib/got_lib_repository.h @@ -21,7 +21,8 @@ enum got_object_chache_type { GOT_OBJECT_CACHE_TYPE_OBJ, - GOT_OBJECT_CACHE_TYPE_TREE + GOT_OBJECT_CACHE_TYPE_TREE, + GOT_OBJECT_CACHE_TYPE_COMMIT, }; struct got_object_cache_entry { @@ -29,6 +30,7 @@ struct got_object_cache_entry { union { struct got_object *obj; struct got_tree_object *tree; + struct got_commit_object *commit; } data; }; @@ -52,6 +54,7 @@ struct got_repository { /* Caches for opened objects. */ struct got_object_cache objcache; struct got_object_cache treecache; + struct got_object_cache commitcache; }; const struct got_error*got_repo_cache_object(struct got_repository *, @@ -62,3 +65,7 @@ const struct got_error*got_repo_cache_tree(struct got_ struct got_object_id *, struct got_tree_object *); struct got_tree_object *got_repo_get_cached_tree(struct got_repository *, struct got_object_id *); +const struct got_error*got_repo_cache_commit(struct got_repository *, + struct got_object_id *, struct got_commit_object *); +struct got_commit_object *got_repo_get_cached_commit(struct got_repository *, + struct got_object_id *); blob - 07109c33e693f77141506e564316ba71e746ba5e blob + 499cfb5cf31ce4b89b028472a453d69fcbafcb54 --- lib/object.c +++ lib/object.c @@ -970,6 +970,12 @@ got_object_commit_open(struct got_commit_object **comm struct got_repository *repo, struct got_object *obj) { const struct got_error *err = NULL; + + *commit = got_repo_get_cached_commit(repo, &obj->id); + if (*commit != NULL) { + (*commit)->refcnt++; + return NULL; + } if (obj->type != GOT_OBJ_TYPE_COMMIT) return got_error(GOT_ERR_OBJ_TYPE); @@ -991,6 +997,12 @@ got_object_commit_open(struct got_commit_object **comm err = read_commit_object_privsep(commit, repo, obj, fd); close(fd); } + + if (err == NULL) { + (*commit)->refcnt++; + err = got_repo_cache_commit(repo, &obj->id, *commit); + } + return err; } @@ -998,6 +1010,11 @@ void got_object_commit_close(struct got_commit_object *commit) { struct got_object_qid *qid; + + if (commit->refcnt > 0) { + commit->refcnt--; + return; + } while (!SIMPLEQ_EMPTY(&commit->parent_ids)) { qid = SIMPLEQ_FIRST(&commit->parent_ids); blob - a688bdaa5e2ba19b4cd1972d21e8d8d99c37f0e5 blob + 73293f2c64aea38647a40355fd9003ca7cae5f77 --- lib/repository.c +++ lib/repository.c @@ -169,6 +169,9 @@ cache_add(struct got_object_cache *cache, struct got_o case GOT_OBJECT_CACHE_TYPE_TREE: got_object_tree_close(ce->data.tree); break; + case GOT_OBJECT_CACHE_TYPE_COMMIT: + got_object_commit_close(ce->data.commit); + break; } free(ce); } @@ -184,6 +187,9 @@ cache_add(struct got_object_cache *cache, struct got_o case GOT_OBJECT_CACHE_TYPE_TREE: ce->data.tree = (struct got_tree_object *)item; break; + case GOT_OBJECT_CACHE_TYPE_COMMIT: + ce->data.commit = (struct got_commit_object *)item; + break; } err = got_object_idset_add(NULL, cache->set, id, ce); if (err) { @@ -253,10 +259,39 @@ got_repo_get_cached_tree(struct got_repository *repo, } repo->treecache.cache_miss++; + return NULL; +} + +const struct got_error * +got_repo_cache_commit(struct got_repository *repo, struct got_object_id *id, + struct got_commit_object *commit) +{ + const struct got_error *err = NULL; + + err = cache_add(&repo->commitcache, id, commit); + if (err) + return err; + + commit->refcnt++; return NULL; } +struct got_commit_object * +got_repo_get_cached_commit(struct got_repository *repo, + struct got_object_id *id) +{ + struct got_object_cache_entry *ce; + ce = got_object_idset_get(repo->commitcache.set, id); + if (ce) { + repo->commitcache.cache_hit++; + return ce->data.commit; + } + + repo->commitcache.cache_miss++; + return NULL; +} + const struct got_error * got_repo_open(struct got_repository **ret, const char *path) { @@ -291,6 +326,13 @@ got_repo_open(struct got_repository **ret, const char } repo->treecache.type = GOT_OBJECT_CACHE_TYPE_TREE; + repo->commitcache.set = got_object_idset_alloc(); + if (repo->commitcache.set == NULL) { + err = got_error_from_errno(); + goto done; + } + repo->commitcache.type = GOT_OBJECT_CACHE_TYPE_COMMIT; + repo->path = got_path_normalize(abspath); if (repo->path == NULL) { err = got_error(GOT_ERR_BAD_PATH); @@ -345,6 +387,16 @@ done: return err; } +static void +print_cache_stats(struct got_object_cache *cache, const char *name) +{ +#if 0 + fprintf(stderr, "%s cache: %d elements, %d hits, %d missed\n", + name, got_object_idset_num_elements(cache->set), cache->cache_hit, + cache->cache_miss); +#endif +} + void got_repo_close(struct got_repository *repo) { @@ -364,9 +416,14 @@ got_repo_close(struct got_repository *repo) free(repo->path); free(repo->path_git_dir); + print_cache_stats(&repo->objcache, "object"); + print_cache_stats(&repo->treecache, "tree"); + print_cache_stats(&repo->commitcache, "commit"); if (repo->objcache.set) got_object_idset_free(repo->objcache.set); if (repo->treecache.set) got_object_idset_free(repo->treecache.set); + if (repo->commitcache.set) + got_object_idset_free(repo->commitcache.set); free(repo); }