|
Packit Service |
20376f |
/*
|
|
Packit Service |
20376f |
* Copyright (C) the libgit2 contributors. All rights reserved.
|
|
Packit Service |
20376f |
*
|
|
Packit Service |
20376f |
* This file is part of libgit2, distributed under the GNU GPL v2 with
|
|
Packit Service |
20376f |
* a Linking Exception. For full terms see the included COPYING file.
|
|
Packit Service |
20376f |
*/
|
|
Packit Service |
20376f |
|
|
Packit Service |
20376f |
#include "common.h"
|
|
Packit Service |
20376f |
#include "git2/object.h"
|
|
Packit Service |
20376f |
#include "git2/sys/odb_backend.h"
|
|
Packit Service |
20376f |
#include "git2/sys/mempack.h"
|
|
Packit Service |
20376f |
#include "fileops.h"
|
|
Packit Service |
20376f |
#include "hash.h"
|
|
Packit Service |
20376f |
#include "odb.h"
|
|
Packit Service |
20376f |
#include "array.h"
|
|
Packit Service |
20376f |
#include "oidmap.h"
|
|
Packit Service |
20376f |
|
|
Packit Service |
20376f |
#include "git2/odb_backend.h"
|
|
Packit Service |
20376f |
#include "git2/types.h"
|
|
Packit Service |
20376f |
#include "git2/pack.h"
|
|
Packit Service |
20376f |
|
|
Packit Service |
20376f |
struct memobject {
|
|
Packit Service |
20376f |
git_oid oid;
|
|
Packit Service |
20376f |
size_t len;
|
|
Packit Service |
20376f |
git_otype type;
|
|
Packit Service |
20376f |
char data[GIT_FLEX_ARRAY];
|
|
Packit Service |
20376f |
};
|
|
Packit Service |
20376f |
|
|
Packit Service |
20376f |
struct memory_packer_db {
|
|
Packit Service |
20376f |
git_odb_backend parent;
|
|
Packit Service |
20376f |
git_oidmap *objects;
|
|
Packit Service |
20376f |
git_array_t(struct memobject *) commits;
|
|
Packit Service |
20376f |
};
|
|
Packit Service |
20376f |
|
|
Packit Service |
20376f |
static int impl__write(git_odb_backend *_backend, const git_oid *oid, const void *data, size_t len, git_otype type)
|
|
Packit Service |
20376f |
{
|
|
Packit Service |
20376f |
struct memory_packer_db *db = (struct memory_packer_db *)_backend;
|
|
Packit Service |
20376f |
struct memobject *obj = NULL;
|
|
Packit Service |
20376f |
khiter_t pos;
|
|
Packit Service |
20376f |
size_t alloc_len;
|
|
Packit Service |
20376f |
int rval;
|
|
Packit Service |
20376f |
|
|
Packit Service |
20376f |
pos = git_oidmap_put(db->objects, oid, &rval);
|
|
Packit Service |
20376f |
if (rval < 0)
|
|
Packit Service |
20376f |
return -1;
|
|
Packit Service |
20376f |
|
|
Packit Service |
20376f |
if (rval == 0)
|
|
Packit Service |
20376f |
return 0;
|
|
Packit Service |
20376f |
|
|
Packit Service |
20376f |
GITERR_CHECK_ALLOC_ADD(&alloc_len, sizeof(struct memobject), len);
|
|
Packit Service |
20376f |
obj = git__malloc(alloc_len);
|
|
Packit Service |
20376f |
GITERR_CHECK_ALLOC(obj);
|
|
Packit Service |
20376f |
|
|
Packit Service |
20376f |
memcpy(obj->data, data, len);
|
|
Packit Service |
20376f |
git_oid_cpy(&obj->oid, oid);
|
|
Packit Service |
20376f |
obj->len = len;
|
|
Packit Service |
20376f |
obj->type = type;
|
|
Packit Service |
20376f |
|
|
Packit Service |
20376f |
git_oidmap_set_key_at(db->objects, pos, &obj->oid);
|
|
Packit Service |
20376f |
git_oidmap_set_value_at(db->objects, pos, obj);
|
|
Packit Service |
20376f |
|
|
Packit Service |
20376f |
if (type == GIT_OBJ_COMMIT) {
|
|
Packit Service |
20376f |
struct memobject **store = git_array_alloc(db->commits);
|
|
Packit Service |
20376f |
GITERR_CHECK_ALLOC(store);
|
|
Packit Service |
20376f |
*store = obj;
|
|
Packit Service |
20376f |
}
|
|
Packit Service |
20376f |
|
|
Packit Service |
20376f |
return 0;
|
|
Packit Service |
20376f |
}
|
|
Packit Service |
20376f |
|
|
Packit Service |
20376f |
static int impl__exists(git_odb_backend *backend, const git_oid *oid)
|
|
Packit Service |
20376f |
{
|
|
Packit Service |
20376f |
struct memory_packer_db *db = (struct memory_packer_db *)backend;
|
|
Packit Service |
20376f |
|
|
Packit Service |
20376f |
return git_oidmap_exists(db->objects, oid);
|
|
Packit Service |
20376f |
}
|
|
Packit Service |
20376f |
|
|
Packit Service |
20376f |
static int impl__read(void **buffer_p, size_t *len_p, git_otype *type_p, git_odb_backend *backend, const git_oid *oid)
|
|
Packit Service |
20376f |
{
|
|
Packit Service |
20376f |
struct memory_packer_db *db = (struct memory_packer_db *)backend;
|
|
Packit Service |
20376f |
struct memobject *obj = NULL;
|
|
Packit Service |
20376f |
khiter_t pos;
|
|
Packit Service |
20376f |
|
|
Packit Service |
20376f |
pos = git_oidmap_lookup_index(db->objects, oid);
|
|
Packit Service |
20376f |
if (!git_oidmap_valid_index(db->objects, pos))
|
|
Packit Service |
20376f |
return GIT_ENOTFOUND;
|
|
Packit Service |
20376f |
|
|
Packit Service |
20376f |
obj = git_oidmap_value_at(db->objects, pos);
|
|
Packit Service |
20376f |
|
|
Packit Service |
20376f |
*len_p = obj->len;
|
|
Packit Service |
20376f |
*type_p = obj->type;
|
|
Packit Service |
20376f |
*buffer_p = git__malloc(obj->len);
|
|
Packit Service |
20376f |
GITERR_CHECK_ALLOC(*buffer_p);
|
|
Packit Service |
20376f |
|
|
Packit Service |
20376f |
memcpy(*buffer_p, obj->data, obj->len);
|
|
Packit Service |
20376f |
return 0;
|
|
Packit Service |
20376f |
}
|
|
Packit Service |
20376f |
|
|
Packit Service |
20376f |
static int impl__read_header(size_t *len_p, git_otype *type_p, git_odb_backend *backend, const git_oid *oid)
|
|
Packit Service |
20376f |
{
|
|
Packit Service |
20376f |
struct memory_packer_db *db = (struct memory_packer_db *)backend;
|
|
Packit Service |
20376f |
struct memobject *obj = NULL;
|
|
Packit Service |
20376f |
khiter_t pos;
|
|
Packit Service |
20376f |
|
|
Packit Service |
20376f |
pos = git_oidmap_lookup_index(db->objects, oid);
|
|
Packit Service |
20376f |
if (!git_oidmap_valid_index(db->objects, pos))
|
|
Packit Service |
20376f |
return GIT_ENOTFOUND;
|
|
Packit Service |
20376f |
|
|
Packit Service |
20376f |
obj = git_oidmap_value_at(db->objects, pos);
|
|
Packit Service |
20376f |
|
|
Packit Service |
20376f |
*len_p = obj->len;
|
|
Packit Service |
20376f |
*type_p = obj->type;
|
|
Packit Service |
20376f |
return 0;
|
|
Packit Service |
20376f |
}
|
|
Packit Service |
20376f |
|
|
Packit Service |
20376f |
int git_mempack_dump(git_buf *pack, git_repository *repo, git_odb_backend *_backend)
|
|
Packit Service |
20376f |
{
|
|
Packit Service |
20376f |
struct memory_packer_db *db = (struct memory_packer_db *)_backend;
|
|
Packit Service |
20376f |
git_packbuilder *packbuilder;
|
|
Packit Service |
20376f |
uint32_t i;
|
|
Packit Service |
20376f |
int err = -1;
|
|
Packit Service |
20376f |
|
|
Packit Service |
20376f |
if (git_packbuilder_new(&packbuilder, repo) < 0)
|
|
Packit Service |
20376f |
return -1;
|
|
Packit Service |
20376f |
|
|
Packit Service |
20376f |
for (i = 0; i < db->commits.size; ++i) {
|
|
Packit Service |
20376f |
struct memobject *commit = db->commits.ptr[i];
|
|
Packit Service |
20376f |
|
|
Packit Service |
20376f |
err = git_packbuilder_insert_commit(packbuilder, &commit->oid);
|
|
Packit Service |
20376f |
if (err < 0)
|
|
Packit Service |
20376f |
goto cleanup;
|
|
Packit Service |
20376f |
}
|
|
Packit Service |
20376f |
|
|
Packit Service |
20376f |
err = git_packbuilder_write_buf(pack, packbuilder);
|
|
Packit Service |
20376f |
|
|
Packit Service |
20376f |
cleanup:
|
|
Packit Service |
20376f |
git_packbuilder_free(packbuilder);
|
|
Packit Service |
20376f |
return err;
|
|
Packit Service |
20376f |
}
|
|
Packit Service |
20376f |
|
|
Packit Service |
20376f |
void git_mempack_reset(git_odb_backend *_backend)
|
|
Packit Service |
20376f |
{
|
|
Packit Service |
20376f |
struct memory_packer_db *db = (struct memory_packer_db *)_backend;
|
|
Packit Service |
20376f |
struct memobject *object = NULL;
|
|
Packit Service |
20376f |
|
|
Packit Service |
20376f |
git_oidmap_foreach_value(db->objects, object, {
|
|
Packit Service |
20376f |
git__free(object);
|
|
Packit Service |
20376f |
});
|
|
Packit Service |
20376f |
|
|
Packit Service |
20376f |
git_array_clear(db->commits);
|
|
Packit Service |
20376f |
|
|
Packit Service |
20376f |
git_oidmap_clear(db->objects);
|
|
Packit Service |
20376f |
}
|
|
Packit Service |
20376f |
|
|
Packit Service |
20376f |
static void impl__free(git_odb_backend *_backend)
|
|
Packit Service |
20376f |
{
|
|
Packit Service |
20376f |
struct memory_packer_db *db = (struct memory_packer_db *)_backend;
|
|
Packit Service |
20376f |
|
|
Packit Service |
20376f |
git_oidmap_free(db->objects);
|
|
Packit Service |
20376f |
git__free(db);
|
|
Packit Service |
20376f |
}
|
|
Packit Service |
20376f |
|
|
Packit Service |
20376f |
int git_mempack_new(git_odb_backend **out)
|
|
Packit Service |
20376f |
{
|
|
Packit Service |
20376f |
struct memory_packer_db *db;
|
|
Packit Service |
20376f |
|
|
Packit Service |
20376f |
assert(out);
|
|
Packit Service |
20376f |
|
|
Packit Service |
20376f |
db = git__calloc(1, sizeof(struct memory_packer_db));
|
|
Packit Service |
20376f |
GITERR_CHECK_ALLOC(db);
|
|
Packit Service |
20376f |
|
|
Packit Service |
20376f |
db->objects = git_oidmap_alloc();
|
|
Packit Service |
20376f |
|
|
Packit Service |
20376f |
db->parent.version = GIT_ODB_BACKEND_VERSION;
|
|
Packit Service |
20376f |
db->parent.read = &impl__read;
|
|
Packit Service |
20376f |
db->parent.write = &impl__write;
|
|
Packit Service |
20376f |
db->parent.read_header = &impl__read_header;
|
|
Packit Service |
20376f |
db->parent.exists = &impl__exists;
|
|
Packit Service |
20376f |
db->parent.free = &impl__free;
|
|
Packit Service |
20376f |
|
|
Packit Service |
20376f |
*out = (git_odb_backend *)db;
|
|
Packit Service |
20376f |
return 0;
|
|
Packit Service |
20376f |
}
|