Skip to content

Commit 6f67314

Browse files
committed
Merge branch 'ps/odb-in-memory' into seen
* ps/odb-in-memory: odb: generic in-memory source odb/source-inmemory: stub out remaining functions odb/source-inmemory: implement `freshen_object()` callback odb/source-inmemory: implement `count_objects()` callback odb/source-inmemory: implement `find_abbrev_len()` callback odb/source-inmemory: implement `for_each_object()` callback odb/source-inmemory: convert to use oidtree oidtree: add ability to store data cbtree: allow using arbitrary wrapper structures for nodes odb/source-inmemory: implement `write_object_stream()` callback odb/source-inmemory: implement `write_object()` callback odb/source-inmemory: implement `write_object()` callback odb/source-inmemory: implement `read_object_stream()` callback odb/source-inmemory: implement `read_object_info()` callback odb: fix unnecessary call to `find_cached_object()` odb/source-inmemory: implement `free()` callback odb: introduce "in-memory" source
2 parents 41f0474 + 42f908c commit 6f67314

File tree

14 files changed

+532
-115
lines changed

14 files changed

+532
-115
lines changed

Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1219,6 +1219,7 @@ LIB_OBJS += object.o
12191219
LIB_OBJS += odb.o
12201220
LIB_OBJS += odb/source.o
12211221
LIB_OBJS += odb/source-files.o
1222+
LIB_OBJS += odb/source-inmemory.o
12221223
LIB_OBJS += odb/streaming.o
12231224
LIB_OBJS += odb/transaction.o
12241225
LIB_OBJS += oid-array.o

cbtree.c

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,11 @@
77
#include "git-compat-util.h"
88
#include "cbtree.h"
99

10+
static inline uint8_t *cb_node_key(struct cb_tree *t, struct cb_node *node)
11+
{
12+
return (uint8_t *) node + t->key_offset;
13+
}
14+
1015
static struct cb_node *cb_node_of(const void *p)
1116
{
1217
return (struct cb_node *)((uintptr_t)p - 1);
@@ -33,6 +38,7 @@ struct cb_node *cb_insert(struct cb_tree *t, struct cb_node *node, size_t klen)
3338
uint8_t c;
3439
int newdirection;
3540
struct cb_node **wherep, *p;
41+
uint8_t *node_key, *p_key;
3642

3743
assert(!((uintptr_t)node & 1)); /* allocations must be aligned */
3844

@@ -41,23 +47,26 @@ struct cb_node *cb_insert(struct cb_tree *t, struct cb_node *node, size_t klen)
4147
return NULL; /* success */
4248
}
4349

50+
node_key = cb_node_key(t, node);
51+
4452
/* see if a node already exists */
45-
p = cb_internal_best_match(t->root, node->k, klen);
53+
p = cb_internal_best_match(t->root, node_key, klen);
54+
p_key = cb_node_key(t, p);
4655

4756
/* find first differing byte */
4857
for (newbyte = 0; newbyte < klen; newbyte++) {
49-
if (p->k[newbyte] != node->k[newbyte])
58+
if (p_key[newbyte] != node_key[newbyte])
5059
goto different_byte_found;
5160
}
5261
return p; /* element exists, let user deal with it */
5362

5463
different_byte_found:
55-
newotherbits = p->k[newbyte] ^ node->k[newbyte];
64+
newotherbits = p_key[newbyte] ^ node_key[newbyte];
5665
newotherbits |= newotherbits >> 1;
5766
newotherbits |= newotherbits >> 2;
5867
newotherbits |= newotherbits >> 4;
5968
newotherbits = (newotherbits & ~(newotherbits >> 1)) ^ 255;
60-
c = p->k[newbyte];
69+
c = p_key[newbyte];
6170
newdirection = (1 + (newotherbits | c)) >> 8;
6271

6372
node->byte = newbyte;
@@ -78,7 +87,7 @@ struct cb_node *cb_insert(struct cb_tree *t, struct cb_node *node, size_t klen)
7887
break;
7988
if (q->byte == newbyte && q->otherbits > newotherbits)
8089
break;
81-
c = q->byte < klen ? node->k[q->byte] : 0;
90+
c = q->byte < klen ? node_key[q->byte] : 0;
8291
direction = (1 + (q->otherbits | c)) >> 8;
8392
wherep = q->child + direction;
8493
}
@@ -93,7 +102,7 @@ struct cb_node *cb_lookup(struct cb_tree *t, const uint8_t *k, size_t klen)
93102
{
94103
struct cb_node *p = cb_internal_best_match(t->root, k, klen);
95104

96-
return p && !memcmp(p->k, k, klen) ? p : NULL;
105+
return p && !memcmp(cb_node_key(t, p), k, klen) ? p : NULL;
97106
}
98107

99108
static int cb_descend(struct cb_node *p, cb_iter fn, void *arg)
@@ -115,6 +124,7 @@ int cb_each(struct cb_tree *t, const uint8_t *kpfx, size_t klen,
115124
struct cb_node *p = t->root;
116125
struct cb_node *top = p;
117126
size_t i = 0;
127+
uint8_t *p_key;
118128

119129
if (!p)
120130
return 0; /* empty tree */
@@ -130,8 +140,9 @@ int cb_each(struct cb_tree *t, const uint8_t *kpfx, size_t klen,
130140
top = p;
131141
}
132142

143+
p_key = cb_node_key(t, p);
133144
for (i = 0; i < klen; i++) {
134-
if (p->k[i] != kpfx[i])
145+
if (p_key[i] != kpfx[i])
135146
return 0; /* "best" match failed */
136147
}
137148

cbtree.h

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,18 +23,19 @@ struct cb_node {
2323
*/
2424
uint32_t byte;
2525
uint8_t otherbits;
26-
uint8_t k[FLEX_ARRAY]; /* arbitrary data, unaligned */
2726
};
2827

2928
struct cb_tree {
3029
struct cb_node *root;
30+
ptrdiff_t key_offset;
3131
};
3232

33-
#define CBTREE_INIT { 0 }
34-
35-
static inline void cb_init(struct cb_tree *t)
33+
static inline void cb_init(struct cb_tree *t,
34+
ptrdiff_t key_offset)
3635
{
37-
struct cb_tree blank = CBTREE_INIT;
36+
struct cb_tree blank = {
37+
.key_offset = key_offset,
38+
};
3839
memcpy(t, &blank, sizeof(*t));
3940
}
4041

loose.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ static int insert_loose_map(struct odb_source *source,
5757
inserted |= insert_oid_pair(map->to_compat, oid, compat_oid);
5858
inserted |= insert_oid_pair(map->to_storage, compat_oid, oid);
5959
if (inserted)
60-
oidtree_insert(files->loose->cache, compat_oid);
60+
oidtree_insert(files->loose->cache, compat_oid, NULL);
6161

6262
return inserted;
6363
}

meson.build

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -405,6 +405,7 @@ libgit_sources = [
405405
'odb.c',
406406
'odb/source.c',
407407
'odb/source-files.c',
408+
'odb/source-inmemory.c',
408409
'odb/streaming.c',
409410
'odb/transaction.c',
410411
'oid-array.c',

object-file.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1857,6 +1857,7 @@ static int for_each_object_wrapper_cb(const struct object_id *oid,
18571857
}
18581858

18591859
static int for_each_prefixed_object_wrapper_cb(const struct object_id *oid,
1860+
void *node_data UNUSED,
18601861
void *cb_data)
18611862
{
18621863
struct for_each_object_wrapper_data *data = cb_data;
@@ -2002,7 +2003,7 @@ static int append_loose_object(const struct object_id *oid,
20022003
const char *path UNUSED,
20032004
void *data)
20042005
{
2005-
oidtree_insert(data, oid);
2006+
oidtree_insert(data, oid, NULL);
20062007
return 0;
20072008
}
20082009

odb.c

Lines changed: 10 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#include "object-file.h"
1515
#include "object-name.h"
1616
#include "odb.h"
17+
#include "odb/source-inmemory.h"
1718
#include "packfile.h"
1819
#include "path.h"
1920
#include "promisor-remote.h"
@@ -31,40 +32,6 @@
3132
KHASH_INIT(odb_path_map, const char * /* key: odb_path */,
3233
struct odb_source *, 1, fspathhash, fspatheq)
3334

34-
/*
35-
* This is meant to hold a *small* number of objects that you would
36-
* want odb_read_object() to be able to return, but yet you do not want
37-
* to write them into the object store (e.g. a browse-only
38-
* application).
39-
*/
40-
struct cached_object_entry {
41-
struct object_id oid;
42-
struct cached_object {
43-
enum object_type type;
44-
const void *buf;
45-
unsigned long size;
46-
} value;
47-
};
48-
49-
static const struct cached_object *find_cached_object(struct object_database *object_store,
50-
const struct object_id *oid)
51-
{
52-
static const struct cached_object empty_tree = {
53-
.type = OBJ_TREE,
54-
.buf = "",
55-
};
56-
const struct cached_object_entry *co = object_store->cached_objects;
57-
58-
for (size_t i = 0; i < object_store->cached_object_nr; i++, co++)
59-
if (oideq(&co->oid, oid))
60-
return &co->value;
61-
62-
if (oid->algo && oideq(oid, hash_algos[oid->algo].empty_tree))
63-
return &empty_tree;
64-
65-
return NULL;
66-
}
67-
6835
int odb_mkstemp(struct object_database *odb,
6936
struct strbuf *temp_filename, const char *pattern)
7037
{
@@ -584,7 +551,6 @@ static int do_oid_object_info_extended(struct object_database *odb,
584551
const struct object_id *oid,
585552
struct object_info *oi, unsigned flags)
586553
{
587-
const struct cached_object *co;
588554
const struct object_id *real = oid;
589555
int already_retried = 0;
590556

@@ -594,25 +560,8 @@ static int do_oid_object_info_extended(struct object_database *odb,
594560
if (is_null_oid(real))
595561
return -1;
596562

597-
co = find_cached_object(odb, real);
598-
if (co) {
599-
if (oi) {
600-
if (oi->typep)
601-
*(oi->typep) = co->type;
602-
if (oi->sizep)
603-
*(oi->sizep) = co->size;
604-
if (oi->disk_sizep)
605-
*(oi->disk_sizep) = 0;
606-
if (oi->delta_base_oid)
607-
oidclr(oi->delta_base_oid, odb->repo->hash_algo);
608-
if (oi->contentp)
609-
*oi->contentp = xmemdupz(co->buf, co->size);
610-
if (oi->mtimep)
611-
*oi->mtimep = 0;
612-
oi->whence = OI_CACHED;
613-
}
563+
if (!odb_source_read_object_info(odb->inmemory_objects, oid, oi, flags))
614564
return 0;
615-
}
616565

617566
odb_prepare_alternates(odb);
618567

@@ -784,24 +733,12 @@ int odb_pretend_object(struct object_database *odb,
784733
void *buf, unsigned long len, enum object_type type,
785734
struct object_id *oid)
786735
{
787-
struct cached_object_entry *co;
788-
char *co_buf;
789-
790736
hash_object_file(odb->repo->hash_algo, buf, len, type, oid);
791-
if (odb_has_object(odb, oid, 0) ||
792-
find_cached_object(odb, oid))
737+
if (odb_has_object(odb, oid, 0))
793738
return 0;
794739

795-
ALLOC_GROW(odb->cached_objects,
796-
odb->cached_object_nr + 1, odb->cached_object_alloc);
797-
co = &odb->cached_objects[odb->cached_object_nr++];
798-
co->value.size = len;
799-
co->value.type = type;
800-
co_buf = xmalloc(len);
801-
memcpy(co_buf, buf, len);
802-
co->value.buf = co_buf;
803-
oidcpy(&co->oid, oid);
804-
return 0;
740+
return odb_source_write_object(odb->inmemory_objects,
741+
buf, len, type, oid, NULL, 0);
805742
}
806743

807744
void *odb_read_object(struct object_database *odb,
@@ -1083,6 +1020,7 @@ struct object_database *odb_new(struct repository *repo,
10831020
o->sources = odb_source_new(o, primary_source, true);
10841021
o->sources_tail = &o->sources->next;
10851022
o->alternate_db = xstrdup_or_null(secondary_sources);
1023+
o->inmemory_objects = &odb_source_inmemory_new(o)->base;
10861024

10871025
free(to_free);
10881026

@@ -1106,6 +1044,10 @@ static void odb_free_sources(struct object_database *o)
11061044
odb_source_free(o->sources);
11071045
o->sources = next;
11081046
}
1047+
1048+
odb_source_free(o->inmemory_objects);
1049+
o->inmemory_objects = NULL;
1050+
11091051
kh_destroy_odb_path_map(o->source_by_path);
11101052
o->source_by_path = NULL;
11111053
}
@@ -1123,10 +1065,6 @@ void odb_free(struct object_database *o)
11231065
odb_close(o);
11241066
odb_free_sources(o);
11251067

1126-
for (size_t i = 0; i < o->cached_object_nr; i++)
1127-
free((char *) o->cached_objects[i].value.buf);
1128-
free(o->cached_objects);
1129-
11301068
string_list_clear(&o->submodule_source_paths, 0);
11311069

11321070
free(o);

odb.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#include "thread-utils.h"
99

1010
struct cached_object_entry;
11+
struct odb_source_inmemory;
1112
struct packed_git;
1213
struct repository;
1314
struct strbuf;
@@ -80,8 +81,7 @@ struct object_database {
8081
* to write them into the object store (e.g. a browse-only
8182
* application).
8283
*/
83-
struct cached_object_entry *cached_objects;
84-
size_t cached_object_nr, cached_object_alloc;
84+
struct odb_source *inmemory_objects;
8585

8686
/*
8787
* A fast, rough count of the number of objects in the repository.

0 commit comments

Comments
 (0)