Commit e82b1d8119d413101f11883e43119759a433edc4

Stefan Sperling 2019-07-27T19:12:22

switch back to searching packed objects first; it is indeed faster

diff --git a/lib/object.c b/lib/object.c
index da29a06..60a273e 100644
--- a/lib/object.c
+++ b/lib/object.c
@@ -147,10 +147,7 @@ open_loose_object(int *fd, struct got_object_id *id,
 		return err;
 	*fd = open(path, O_RDONLY | O_NOFOLLOW);
 	if (*fd == -1) {
-		if (errno == ENOENT)
-			err = got_error_no_obj(id);
-		else
-			err = got_error_from_errno2("open", path);
+		err = got_error_from_errno2("open", path);
 		goto done;
 	}
 done:
@@ -425,17 +422,25 @@ got_object_open(struct got_object **obj, struct got_repository *repo,
 		return NULL;
 	}
 
+	err = open_packed_object(obj, id, repo);
+	if (err && err->code != GOT_ERR_NO_OBJ)
+		return err;
+	if (*obj) {
+		(*obj)->refcnt++;
+		return got_repo_cache_object(repo, id, *obj);
+	}
+
 	err = got_object_get_path(&path, id, repo);
 	if (err)
 		return err;
 
 	fd = open(path, O_RDONLY | O_NOFOLLOW);
 	if (fd == -1) {
-		if (errno != ENOENT) {
+		if (errno == ENOENT)
+			err = got_error_no_obj(id);
+		else
 			err = got_error_from_errno2("open", path);
-			goto done;
-		}
-		err = open_packed_object(obj, id, repo);
+		goto done;
 	} else {
 		err = read_object_header_privsep(obj, repo, fd);
 		if (err)
@@ -574,7 +579,7 @@ open_commit(struct got_commit_object **commit,
 {
 	const struct got_error *err = NULL;
 	struct got_packidx *packidx = NULL;
-	int idx, fd;
+	int idx;
 	char *path_packfile;
 
 	if (check_cache) {
@@ -586,17 +591,10 @@ open_commit(struct got_commit_object **commit,
 	} else
 		*commit = NULL;
 
-	err = open_loose_object(&fd, id, repo);
-	if (err) {
+	err = got_repo_search_packidx(&packidx, &idx, repo, id);
+	if (err == NULL) {
 		struct got_pack *pack = NULL;
 
-		if (err->code != GOT_ERR_NO_OBJ)
-			return err;
-
-		err = got_repo_search_packidx(&packidx, &idx, repo, id);
-		if (err)
-			return err;
-
 		err = get_packfile_path(&path_packfile, packidx);
 		if (err)
 			return err;
@@ -610,8 +608,14 @@ open_commit(struct got_commit_object **commit,
 		}
 		err = read_packed_commit_privsep(commit, pack,
 		    packidx, idx, id);
-	} else
+	} else if (err->code == GOT_ERR_NO_OBJ) {
+		int fd;
+
+		err = open_loose_object(&fd, id, repo);
+		if (err)
+			return err;
 		err = read_commit_privsep(commit, fd, repo);
+	}
 
 	if (err == NULL) {
 		(*commit)->refcnt++;
@@ -753,7 +757,7 @@ open_tree(struct got_tree_object **tree, struct got_repository *repo,
 {
 	const struct got_error *err = NULL;
 	struct got_packidx *packidx = NULL;
-	int fd, idx;
+	int idx;
 	char *path_packfile;
 
 	if (check_cache) {
@@ -765,32 +769,31 @@ open_tree(struct got_tree_object **tree, struct got_repository *repo,
 	} else
 		*tree = NULL;
 
-	err = open_loose_object(&fd, id, repo);
-	if (err) {
+	err = got_repo_search_packidx(&packidx, &idx, repo, id);
+	if (err == NULL) {
 		struct got_pack *pack = NULL;
 
-		if (err->code != GOT_ERR_NO_OBJ)
-			return err;
-
-		err = got_repo_search_packidx(&packidx, &idx, repo, id);
-		if (err)
-			return err;
-
 		err = get_packfile_path(&path_packfile, packidx);
 		if (err)
 			return err;
 
 		pack = got_repo_get_cached_pack(repo, path_packfile);
 		if (pack == NULL) {
-			err = got_repo_cache_pack(&pack, repo,
-			    path_packfile, packidx);
+			err = got_repo_cache_pack(&pack, repo, path_packfile,
+			    packidx);
 			if (err)
 				return err;
 		}
 		err = read_packed_tree_privsep(tree, pack,
 		    packidx, idx, id);
-	} else
+	} else if (err->code == GOT_ERR_NO_OBJ) {
+		int fd;
+
+		err = open_loose_object(&fd, id, repo);
+		if (err)
+			return err;
 		err = read_tree_privsep(tree, fd, repo);
+	}
 
 	if (err == NULL) {
 		(*tree)->refcnt++;
@@ -976,7 +979,7 @@ open_blob(struct got_blob_object **blob, struct got_repository *repo,
 	int idx;
 	char *path_packfile;
 	uint8_t *outbuf;
-	int infd, outfd;
+	int outfd;
 	size_t size, hdrlen;
 	struct stat sb;
 
@@ -994,17 +997,10 @@ open_blob(struct got_blob_object **blob, struct got_repository *repo,
 		goto done;
 	}
 
-	err = open_loose_object(&infd, id, repo);
-	if (err) {
+	err = got_repo_search_packidx(&packidx, &idx, repo, id);
+	if (err == NULL) {
 		struct got_pack *pack = NULL;
 
-		if (err->code != GOT_ERR_NO_OBJ)
-			goto done;
-
-		err = got_repo_search_packidx(&packidx, &idx, repo, id);
-		if (err)
-			goto done;
-
 		err = get_packfile_path(&path_packfile, packidx);
 		if (err)
 			goto done;
@@ -1018,9 +1014,15 @@ open_blob(struct got_blob_object **blob, struct got_repository *repo,
 		}
 		err = read_packed_blob_privsep(&outbuf, &size, &hdrlen, outfd,
 		    pack, packidx, idx, id);
-	} else
+	} else if (err->code == GOT_ERR_NO_OBJ) {
+		int infd;
+
+		err = open_loose_object(&infd, id, repo);
+		if (err)
+			goto done;
 		err = read_blob_privsep(&outbuf, &size, &hdrlen, outfd, infd,
 		    repo);
+	}
 	if (err)
 		goto done;
 
@@ -1287,7 +1289,7 @@ open_tag(struct got_tag_object **tag, struct got_repository *repo,
 {
 	const struct got_error *err = NULL;
 	struct got_packidx *packidx = NULL;
-	int fd, idx;
+	int idx;
 	char *path_packfile;
 
 	if (check_cache) {
@@ -1299,36 +1301,37 @@ open_tag(struct got_tag_object **tag, struct got_repository *repo,
 	} else
 		*tag = NULL;
 
-	err = open_loose_object(&fd, id, repo);
-	if (err) {
+	err = got_repo_search_packidx(&packidx, &idx, repo, id);
+	if (err == NULL) {
 		struct got_pack *pack = NULL;
 
-		if (err->code != GOT_ERR_NO_OBJ)
-			return err;
-
-		err = got_repo_search_packidx(&packidx, &idx, repo, id);
-		if (err)
-			return err;
-
 		err = get_packfile_path(&path_packfile, packidx);
 		if (err)
 			return err;
 
 		pack = got_repo_get_cached_pack(repo, path_packfile);
 		if (pack == NULL) {
-			err = got_repo_cache_pack(&pack, repo,
-			    path_packfile, packidx);
+			err = got_repo_cache_pack(&pack, repo, path_packfile,
+			    packidx);
 			if (err)
 				return err;
 		}
-		err = read_packed_tag_privsep(tag, pack, packidx, idx, id);
-	} else
+		err = read_packed_tag_privsep(tag, pack,
+		    packidx, idx, id);
+	} else if (err->code == GOT_ERR_NO_OBJ) {
+		int fd;
+
+		err = open_loose_object(&fd, id, repo);
+		if (err)
+			return err;
 		err = read_tag_privsep(tag, fd, repo);
+	}
 
 	if (err == NULL) {
 		(*tag)->refcnt++;
 		err = got_repo_cache_tag(repo, id, *tag);
 	}
+
 	return err;
 }