summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatar Linus Torvalds <torvalds@linux-foundation.org>2014-03-08 13:11:50 -0800
committerGravatar Dirk Hohndel <dirk@hohndel.org>2014-03-09 19:36:33 -0700
commit34fb8240da7632847e36ffd9629a49e1c60b59d6 (patch)
tree6577ca0fc7c907f2bd0fe623efc0a75c97587deb
parentf0985644b618a65fcf876c8ea856746b3c1dbaac (diff)
downloadsubsurface-34fb8240da7632847e36ffd9629a49e1c60b59d6.tar.gz
git repository reading: start reading the actual file contents
If we want to scale to thousands of dives, we'll eventually want to read the dive computer files lazily when actually needed, but for now we do everything synchronously. Even if that may actually be slower than parsing one big XML file. The git object store is pretty efficient, but especially with some history, the compression and delta application will certainly not be free. This does all the git object unpacking, but none of the actual data parsing yet. But as part of looking up the file objects, we do get the dive number (which is in the name of the dive file). Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
-rw-r--r--load-git.c69
1 files changed, 64 insertions, 5 deletions
diff --git a/load-git.c b/load-git.c
index 60159381f..79c17ef22 100644
--- a/load-git.c
+++ b/load-git.c
@@ -244,25 +244,84 @@ static int walk_tree_directory(const char *root, const git_tree_entry *entry)
return dive_trip_directory(root, name);
}
-static int walk_tree_file(const char *root, const git_tree_entry *entry)
+git_blob *git_tree_entry_blob(git_repository *repo, const git_tree_entry *entry)
{
- /* Parse actual dive/trip data here */
- return GIT_WALK_OK;
+ const git_oid *id = git_tree_entry_id(entry);
+ git_blob *blob;
+
+ if (git_blob_lookup(&blob, repo, id))
+ return NULL;
+ return blob;
+}
+
+/*
+ * We should *really* try to delay the dive computer data parsing
+ * until necessary, in order to reduce load-time. The parsing is
+ * cheap, but the loading of the git blob into memory can be pretty
+ * costly.
+ */
+static int parse_divecomputer_entry(git_repository *repo, const git_tree_entry *entry, const char *suffix)
+{
+ git_blob *blob = git_tree_entry_blob(repo, entry);
+ if (!blob)
+ return report_error("Unable to read divecomputer file");
+ git_blob_free(blob);
+ return 0;
+}
+
+static int parse_dive_entry(git_repository *repo, const git_tree_entry *entry, const char *suffix)
+{
+ struct dive *dive = active_dive;
+ git_blob *blob = git_tree_entry_blob(repo, entry);
+ if (!blob)
+ return report_error("Unable to read dive file");
+ if (*suffix)
+ dive->number = atoi(suffix+1);
+ git_blob_free(blob);
+ return 0;
+}
+
+static int parse_trip_entry(git_repository *repo, const git_tree_entry *entry)
+{
+ git_blob *blob = git_tree_entry_blob(repo, entry);
+ if (!blob)
+ return report_error("Unable to read trip file");
+ git_blob_free(blob);
+ return 0;
+}
+
+static int walk_tree_file(const char *root, const git_tree_entry *entry, git_repository *repo)
+{
+ struct dive *dive = active_dive;
+ dive_trip_t *trip = active_trip;
+ const char *name = git_tree_entry_name(entry);
+
+ if (dive && !strncmp(name, "Divecomputer", 12))
+ return parse_divecomputer_entry(repo, entry, name+12);
+ if (dive && !strncmp(name, "Dive", 4))
+ return parse_dive_entry(repo, entry, name+4);
+ if (trip && !strcmp(name, "00-Trip"))
+ return parse_trip_entry(repo, entry);
+ report_error("Unknown file %s%s (%p %p)", root, name, dive, trip);
+ return GIT_WALK_SKIP;
}
static int walk_tree_cb(const char *root, const git_tree_entry *entry, void *payload)
{
+ git_repository *repo = payload;
git_filemode_t mode = git_tree_entry_filemode(entry);
if (mode == GIT_FILEMODE_TREE)
return walk_tree_directory(root, entry);
- return walk_tree_file(root, entry);
+ walk_tree_file(root, entry, repo);
+ /* Ignore failed blob loads */
+ return GIT_WALK_OK;
}
static int load_dives_from_tree(git_repository *repo, git_tree *tree)
{
- git_tree_walk(tree, GIT_TREEWALK_PRE, walk_tree_cb, NULL);
+ git_tree_walk(tree, GIT_TREEWALK_PRE, walk_tree_cb, repo);
return 0;
}