summaryrefslogtreecommitdiff
path: root/src/refs.c
diff options
context:
space:
mode:
authorVicent Marti <tanoku@gmail.com>2011-02-21 17:05:16 +0200
committerVicent Marti <tanoku@gmail.com>2011-02-21 18:13:43 +0200
commit817c28201e2a9564b38a624be491245aa025c77f (patch)
treedfcf8639c04f6e1ddfe3eb6b9980dc0b3d06cd21 /src/refs.c
parent874c3b6f37e291233be389dbacdb7178af85ad2f (diff)
downloadlibgit2-817c28201e2a9564b38a624be491245aa025c77f.tar.gz
Rewrite all file IO for more performance
The new `git_filebuf` structure provides atomic high-performance writes to disk by using a write cache, and optionally a double-buffered scheme through a worker thread (not enabled yet). Writes can be done 3-layered, like in git.git (user code -> write cache -> disk), or 2-layered, by writing directly on the cache. This makes index writing considerably faster. The `git_filebuf` structure contains all the old functionality of `git_filelock` for atomic file writes and reads. The `git_filelock` structure has been removed. Additionally, the `git_filebuf` API allows to automatically hash (SHA1) all the data as it is written to disk (hashing is done smartly on big chunks to improve performance). Signed-off-by: Vicent Marti <tanoku@gmail.com>
Diffstat (limited to 'src/refs.c')
-rw-r--r--src/refs.c22
1 files changed, 10 insertions, 12 deletions
diff --git a/src/refs.c b/src/refs.c
index a3055650f..1f434ea03 100644
--- a/src/refs.c
+++ b/src/refs.c
@@ -511,7 +511,7 @@ int git_reference_resolve(git_reference **resolved_ref, git_reference *ref)
int git_reference_write(git_reference *ref)
{
- git_filelock lock;
+ git_filebuf file;
char ref_path[GIT_PATH_MAX];
int error, contents_size;
char *ref_contents = NULL;
@@ -528,10 +528,7 @@ int git_reference_write(git_reference *ref)
git__joinpath(ref_path, ref->owner->path_repository, ref->name);
- if ((error = git_filelock_init(&lock, ref_path)) < GIT_SUCCESS)
- goto error_cleanup;
-
- if ((error = git_filelock_lock(&lock, 0)) < GIT_SUCCESS)
+ if ((error = git_filebuf_open(&file, ref_path, 0)) < GIT_SUCCESS)
goto error_cleanup;
if (ref->type == GIT_REF_OID) {
@@ -560,20 +557,21 @@ int git_reference_write(git_reference *ref)
ref_contents[contents_size - 1] = '\n';
}
- if ((error = git_filelock_write(&lock, ref_contents, contents_size)) < GIT_SUCCESS)
+ if ((error = git_filebuf_write(&file, ref_contents, contents_size)) < GIT_SUCCESS)
goto error_cleanup;
- if ((error = git_filelock_commit(&lock)) < GIT_SUCCESS)
- goto error_cleanup;
+ free(ref_contents);
- ref->modified = 0;
+ error = git_filebuf_commit(&file);
- free(ref_contents);
- return GIT_SUCCESS;
+ if (error == GIT_SUCCESS)
+ ref->modified = 0;
+
+ return error;
error_cleanup:
free(ref_contents);
- git_filelock_unlock(&lock);
+ git_filebuf_cleanup(&file);
return error;
}