diff options
| author | Vicent Marti <tanoku@gmail.com> | 2011-02-21 17:05:16 +0200 |
|---|---|---|
| committer | Vicent Marti <tanoku@gmail.com> | 2011-02-21 18:13:43 +0200 |
| commit | 817c28201e2a9564b38a624be491245aa025c77f (patch) | |
| tree | dfcf8639c04f6e1ddfe3eb6b9980dc0b3d06cd21 /src/filelock.c | |
| parent | 874c3b6f37e291233be389dbacdb7178af85ad2f (diff) | |
| download | libgit2-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/filelock.c')
| -rw-r--r-- | src/filelock.c | 132 |
1 files changed, 0 insertions, 132 deletions
diff --git a/src/filelock.c b/src/filelock.c deleted file mode 100644 index 9db1cd720..000000000 --- a/src/filelock.c +++ /dev/null @@ -1,132 +0,0 @@ -/* - * This file is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License, version 2, - * as published by the Free Software Foundation. - * - * In addition to the permissions in the GNU General Public License, - * the authors give you unlimited permission to link the compiled - * version of this file into combinations with other programs, - * and to distribute those combinations without any restriction - * coming from the use of this file. (The General Public License - * restrictions do apply in other respects; for example, they cover - * modification of the file, and distribution when not linked into - * a combined executable.) - * - * This file is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; see the file COPYING. If not, write to - * the Free Software Foundation, 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -#include "common.h" -#include "filelock.h" -#include "fileops.h" - -static const char *GIT_FILELOCK_EXTENSION = ".lock\0"; -static const size_t GIT_FILELOCK_EXTLENGTH = 6; - -#define BUILD_PATH_LOCK(_lock, _path) { \ - memcpy(_path, _lock->path, _lock->path_length); \ - memcpy(_path + _lock->path_length, GIT_FILELOCK_EXTENSION,\ - GIT_FILELOCK_EXTLENGTH);\ -} - -int git_filelock_init(git_filelock *lock, const char *path) -{ - if (lock == NULL || path == NULL) - return GIT_ERROR; - - memset(lock, 0x0, sizeof(git_filelock)); - - lock->path_length = strlen(path); - - if (lock->path_length + GIT_FILELOCK_EXTLENGTH >= GIT_PATH_MAX) - return GIT_ERROR; - - memcpy(lock->path, path, lock->path_length); - return GIT_SUCCESS; -} - -int git_filelock_lock(git_filelock *lock, int append) -{ - char path_lock[GIT_PATH_MAX]; - BUILD_PATH_LOCK(lock, path_lock); - - /* If file already exists, we cannot create a lock */ - if (gitfo_exists(path_lock) == 0) - return GIT_EOSERR; - - lock->file_lock = gitfo_creat(path_lock, 0666); - - if (lock->file_lock < 0) - return GIT_EOSERR; - - lock->is_locked = 1; - - /* TODO: do a flock() in the descriptor file_lock */ - - if (append && gitfo_exists(lock->path) == 0) { - git_file source; - char buffer[2048]; - size_t read_bytes; - - source = gitfo_open(lock->path, O_RDONLY); - if (source < 0) - return GIT_EOSERR; - - while ((read_bytes = gitfo_read(source, buffer, 2048)) > 0) - gitfo_write(lock->file_lock, buffer, read_bytes); - - gitfo_close(source); - } - - return GIT_SUCCESS; -} - -void git_filelock_unlock(git_filelock *lock) -{ - char path_lock[GIT_PATH_MAX]; - BUILD_PATH_LOCK(lock, path_lock); - - if (lock->is_locked) { - /* The flock() in lock->file_lock is removed - * automatically when closing the descriptor */ - gitfo_close(lock->file_lock); - gitfo_unlink(path_lock); - lock->is_locked = 0; - } -} - -int git_filelock_commit(git_filelock *lock) -{ - int error; - char path_lock[GIT_PATH_MAX]; - BUILD_PATH_LOCK(lock, path_lock); - - if (!lock->is_locked || lock->file_lock < 0) - return GIT_ERROR; - - /* FIXME: flush the descriptor? */ - gitfo_close(lock->file_lock); - - error = gitfo_move_file(path_lock, lock->path); - - if (error < GIT_SUCCESS) - gitfo_unlink(path_lock); - - lock->is_locked = 0; - return error; -} - -int git_filelock_write(git_filelock *lock, const void *buffer, size_t length) -{ - if (!lock->is_locked || lock->file_lock < 0) - return GIT_ERROR; - - return gitfo_write(lock->file_lock, (void *)buffer, length); -} |
