Commit a7a7ddbe by Vicent Marti

Add generic methods for object writeback

git_repository_object has now several internal methods to write back the
object information in the repository.

- git_repository__dbo_prepare_write()
	Prepares the DBO object to be modified

- git_repository__dbo_write()
	Writes new bytes to the DBO object

- git_repository__dbo_writeback()
	Writes back the changes to the repository

Signed-off-by: Vicent Marti <tanoku@gmail.com>
parent 46f8566a
...@@ -69,14 +69,14 @@ int git_commit__parse(git_commit *commit, unsigned int parse_flags, int close_db ...@@ -69,14 +69,14 @@ int git_commit__parse(git_commit *commit, unsigned int parse_flags, int close_db
{ {
int error = 0; int error = 0;
if ((error = git_repository__open_dbo((git_repository_object *)commit)) < 0) if ((error = git_repository__dbo_open((git_repository_object *)commit)) < 0)
return error; return error;
error = git_commit__parse_buffer(commit, error = git_commit__parse_buffer(commit,
commit->object.dbo.data, commit->object.dbo.len, parse_flags); commit->object.dbo.data, commit->object.dbo.len, parse_flags);
if (close_db_object) if (close_db_object)
git_repository__close_dbo((git_repository_object *)commit); git_repository__dbo_close((git_repository_object *)commit);
return error; return error;
} }
......
...@@ -91,10 +91,84 @@ void git_repository_free(git_repository *repo) ...@@ -91,10 +91,84 @@ void git_repository_free(git_repository *repo)
free(repo); free(repo);
} }
int git_repository__open_dbo(git_repository_object *object) void git_repository__dbo_prepare_write(git_repository_object *object)
{
size_t base_size = 512;
if (object->writeback.write_ptr != NULL || object->dbo_open)
git_repository__dbo_close(object);
/* TODO: proper size calculation */
object->dbo.data = git__malloc(base_size);
object->dbo.len = 0;
object->writeback.write_ptr = object->dbo.data;
object->writeback.ptr_size = base_size;
object->writeback.written_bytes = 0;
object->dbo_open = 1;
object->out_of_sync = 1;
}
int git_repository__dbo_write(git_repository_object *object, const void *bytes, size_t len)
{
assert(object);
if (!object->dbo_open || object->writeback.write_ptr == NULL)
return GIT_ERROR;
/* TODO: resize buffer on overflow */
if (object->writeback.written_bytes + len >= object->writeback.ptr_size)
return GIT_ENOMEM;
memcpy(object->writeback.write_ptr, bytes, len);
object->writeback.write_ptr += len;
object->writeback.written_bytes += len;
return GIT_SUCCESS;
}
int git_repository__dbo_writeback(git_repository_object *object)
{
int error;
git_oid new_id;
assert(object);
if (!object->dbo_open)
return GIT_ERROR;
if (!object->out_of_sync)
return GIT_SUCCESS;
object->dbo.len = object->writeback.written_bytes;
git_obj_hash(&new_id, &object->dbo);
if ((error = git_odb_write(&new_id, object->repo->db, &object->dbo)) < 0)
return error;
git_hashtable_remove(object->repo->objects, &object->id);
git_oid_cpy(&object->id, &new_id);
git_hashtable_insert(object->repo->objects, &object->id, object);
object->writeback.write_ptr = NULL;
object->writeback.ptr_size = 0;
object->writeback.written_bytes = 0;
git_repository__dbo_close(object);
return GIT_SUCCESS;
}
int git_repository__dbo_open(git_repository_object *object)
{ {
int error; int error;
assert(object);
if (object->dbo_open && object->out_of_sync)
git_repository__dbo_close(object);
if (object->dbo_open) if (object->dbo_open)
return GIT_SUCCESS; return GIT_SUCCESS;
...@@ -103,19 +177,25 @@ int git_repository__open_dbo(git_repository_object *object) ...@@ -103,19 +177,25 @@ int git_repository__open_dbo(git_repository_object *object)
return error; return error;
object->dbo_open = 1; object->dbo_open = 1;
object->out_of_sync = 0;
return GIT_SUCCESS; return GIT_SUCCESS;
} }
void git_repository__close_dbo(git_repository_object *object) void git_repository__dbo_close(git_repository_object *object)
{ {
assert(object);
if (!object->dbo_open) { if (!object->dbo_open) {
git_obj_close(&object->dbo); git_obj_close(&object->dbo);
object->dbo_open = 0; object->dbo_open = 0;
object->out_of_sync = 0;
} }
} }
void git_repository_object_free(git_repository_object *object) void git_repository_object_free(git_repository_object *object)
{ {
assert(object);
git_hashtable_remove(object->repo->objects, &object->id); git_hashtable_remove(object->repo->objects, &object->id);
git_obj_close(&object->dbo); git_obj_close(&object->dbo);
......
...@@ -12,7 +12,14 @@ struct git_repository_object { ...@@ -12,7 +12,14 @@ struct git_repository_object {
git_oid id; git_oid id;
git_repository *repo; git_repository *repo;
git_obj dbo; git_obj dbo;
int dbo_open;
struct {
void *write_ptr;
size_t ptr_size;
size_t written_bytes;
} writeback;
int dbo_open:1, out_of_sync:1;
}; };
struct git_repository { struct git_repository {
...@@ -21,7 +28,10 @@ struct git_repository { ...@@ -21,7 +28,10 @@ struct git_repository {
}; };
int git_repository__open_dbo(git_repository_object *object); int git_repository__dbo_open(git_repository_object *object);
void git_repository__close_dbo(git_repository_object *object); void git_repository__dbo_close(git_repository_object *object);
void git_repository__dbo_prepare_write(git_repository_object *object);
int git_repository__dbo_write(git_repository_object *object, const void *bytes, size_t len);
int git_repository__dbo_writeback(git_repository_object *object);
#endif #endif
...@@ -161,13 +161,13 @@ int git_tag__parse(git_tag *tag) ...@@ -161,13 +161,13 @@ int git_tag__parse(git_tag *tag)
{ {
int error = 0; int error = 0;
error = git_repository__open_dbo((git_repository_object *)tag); error = git_repository__dbo_open((git_repository_object *)tag);
if (error < 0) if (error < 0)
return error; return error;
error = parse_tag_buffer(tag, tag->object.dbo.data, tag->object.dbo.data + tag->object.dbo.len); error = parse_tag_buffer(tag, tag->object.dbo.data, tag->object.dbo.data + tag->object.dbo.len);
git_repository__close_dbo((git_repository_object *)tag); git_repository__dbo_close((git_repository_object *)tag);
return error; return error;
} }
......
...@@ -107,7 +107,7 @@ int git_tree__parse(git_tree *tree) ...@@ -107,7 +107,7 @@ int git_tree__parse(git_tree *tree)
if (tree->entries != NULL) if (tree->entries != NULL)
return GIT_SUCCESS; return GIT_SUCCESS;
error = git_repository__open_dbo((git_repository_object *)tree); error = git_repository__dbo_open((git_repository_object *)tree);
if (error < 0) if (error < 0)
return error; return error;
...@@ -155,6 +155,6 @@ int git_tree__parse(git_tree *tree) ...@@ -155,6 +155,6 @@ int git_tree__parse(git_tree *tree)
buffer += GIT_OID_RAWSZ; buffer += GIT_OID_RAWSZ;
} }
git_repository__close_dbo((git_repository_object *)tree); git_repository__dbo_close((git_repository_object *)tree);
return error; return error;
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment