Commit 1699efc4217d925c50abee60d196d9f6e738a72e

Shawn O. Pearce 2008-11-03T18:39:37

Implement some of the basic git_odb open and close API Far from being complete, but its a good start. Signed-off-by: Shawn O. Pearce <spearce@spearce.org>

diff --git a/include/git/odb.h b/include/git/odb.h
index 7c6be4f..0d65e19 100644
--- a/include/git/odb.h
+++ b/include/git/odb.h
@@ -54,9 +54,8 @@ GIT_EXTERN(int) git_odb_open(git_odb **out, const char *objects_dir);
 /**
  * Close an open object database.
  * @param db database pointer to close.  If NULL no action is taken.
- *           The pointer is set to NULL when the close is completed.
  */
-GIT_EXTERN(void) git_odb_close(git_odb **db);
+GIT_EXTERN(void) git_odb_close(git_odb *db);
 
 /** Basic type (loose or packed) of any Git object. */
 typedef enum {
@@ -129,7 +128,11 @@ GIT_EXTERN(int) git_odb__read_loose(git_sobj *out, git_odb *db, const git_oid *i
  *
  * @param obj object descriptor to free.
  */
-GIT_EXTERN(void) git_sobj_close(git_sobj *obj);
+GIT_INLINE(void) git_sobj_close(git_sobj *obj)
+{
+	free(obj->data);
+	obj->data = NULL;
+}
 
 /** @} */
 GIT_END_DECL
diff --git a/src/odb.c b/src/odb.c
index 86dcfa9..0a42099 100644
--- a/src/odb.c
+++ b/src/odb.c
@@ -27,21 +27,71 @@
 
 struct git_odb {
 	/** Path to the "objects" directory. */
-	const char *path;
+	char *path;
 
 	/** Alternate databases to search. */
 	git_odb **alternates;
-
-	/** Number of alternates available. */
-	unsigned n_alternates;
 };
 
+static int open_alternates(git_odb *db)
+{
+	unsigned n = 0;
+
+	db->alternates = malloc(sizeof(*db->alternates) * (n + 1));
+	if (!db->alternates)
+		return GIT_ERROR;
+
+	db->alternates[n] = NULL;
+	return GIT_SUCCESS;
+}
+
+int git_odb_open(git_odb **out, const char *objects_dir)
+{
+	git_odb *db = malloc(sizeof(*db));
+	if (!db)
+		return GIT_ERROR;
+
+	db->path = strdup(objects_dir);
+	if (!db->path) {
+		free(db);
+		return GIT_ERROR;
+	}
+
+	db->alternates = NULL;
+
+	*out = db;
+	return GIT_SUCCESS;
+}
+
+void git_odb_close(git_odb *db)
+{
+	if (!db)
+		return;
+
+	if (db->alternates) {
+		git_odb **alt;
+		for (alt = db->alternates; *alt; alt++)
+			git_odb_close(*alt);
+		free(db->alternates);
+	}
+
+	free(db->path);
+	free(db);
+}
+
 int git_odb_read(
 	git_sobj *out,
 	git_odb *db,
 	const git_oid *id)
 {
+attempt:
 	if (!git_odb__read_packed(out, db, id))
 		return GIT_SUCCESS;
-	return git_odb__read_loose(out, db, id);
+	if (!git_odb__read_loose(out, db, id))
+		return GIT_SUCCESS;
+	if (!db->alternates && !open_alternates(db))
+		goto attempt;
+
+	out->data = NULL;
+	return GIT_ENOTFOUND;
 }