Skip to content

Commit ff7ad5c

Browse files
pks-tgitster
authored andcommitted
object-file: read objects via the loose object source
When reading an object via `loose_object_info()` or `map_loose_object()` we hand in the whole repository. We then iterate through each of the object sources to figure out whether that source has the object in question. This logic is reversing responsibility though: a specific backend should only care about one specific source, where the object sources themselves are then managed by the object database. Refactor the code accordingly by passing an object source to both of these functions instead. The different sources are then handled by either `do_oid_object_info_extended()`, which sits on the object database level, and by `open_istream_loose()`. The latter function arguably is still at the wrong level, but this will be cleaned up at a later point in time. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
1 parent 376016e commit ff7ad5c

File tree

4 files changed

+50
-53
lines changed

4 files changed

+50
-53
lines changed

object-file.c

Lines changed: 25 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -167,25 +167,22 @@ int stream_object_signature(struct repository *r, const struct object_id *oid)
167167
}
168168

169169
/*
170-
* Find "oid" as a loose object in the local repository or in an alternate.
170+
* Find "oid" as a loose object in given source.
171171
* Returns 0 on success, negative on failure.
172172
*
173173
* The "path" out-parameter will give the path of the object we found (if any).
174174
* Note that it may point to static storage and is only valid until another
175175
* call to stat_loose_object().
176176
*/
177-
static int stat_loose_object(struct repository *r, const struct object_id *oid,
177+
static int stat_loose_object(struct odb_source_loose *loose,
178+
const struct object_id *oid,
178179
struct stat *st, const char **path)
179180
{
180-
struct odb_source *source;
181181
static struct strbuf buf = STRBUF_INIT;
182182

183-
odb_prepare_alternates(r->objects);
184-
for (source = r->objects->sources; source; source = source->next) {
185-
*path = odb_loose_path(source, &buf, oid);
186-
if (!lstat(*path, st))
187-
return 0;
188-
}
183+
*path = odb_loose_path(loose->source, &buf, oid);
184+
if (!lstat(*path, st))
185+
return 0;
189186

190187
return -1;
191188
}
@@ -194,39 +191,24 @@ static int stat_loose_object(struct repository *r, const struct object_id *oid,
194191
* Like stat_loose_object(), but actually open the object and return the
195192
* descriptor. See the caveats on the "path" parameter above.
196193
*/
197-
static int open_loose_object(struct repository *r,
194+
static int open_loose_object(struct odb_source_loose *loose,
198195
const struct object_id *oid, const char **path)
199196
{
200-
int fd;
201-
struct odb_source *source;
202-
int most_interesting_errno = ENOENT;
203197
static struct strbuf buf = STRBUF_INIT;
198+
int fd;
204199

205-
odb_prepare_alternates(r->objects);
206-
for (source = r->objects->sources; source; source = source->next) {
207-
*path = odb_loose_path(source, &buf, oid);
208-
fd = git_open(*path);
209-
if (fd >= 0)
210-
return fd;
200+
*path = odb_loose_path(loose->source, &buf, oid);
201+
fd = git_open(*path);
202+
if (fd >= 0)
203+
return fd;
211204

212-
if (most_interesting_errno == ENOENT)
213-
most_interesting_errno = errno;
214-
}
215-
errno = most_interesting_errno;
216205
return -1;
217206
}
218207

219-
static int quick_has_loose(struct repository *r,
208+
static int quick_has_loose(struct odb_source_loose *loose,
220209
const struct object_id *oid)
221210
{
222-
struct odb_source *source;
223-
224-
odb_prepare_alternates(r->objects);
225-
for (source = r->objects->sources; source; source = source->next) {
226-
if (oidtree_contains(odb_source_loose_cache(source, oid), oid))
227-
return 1;
228-
}
229-
return 0;
211+
return !!oidtree_contains(odb_source_loose_cache(loose->source, oid), oid);
230212
}
231213

232214
/*
@@ -252,12 +234,12 @@ static void *map_fd(int fd, const char *path, unsigned long *size)
252234
return map;
253235
}
254236

255-
void *map_loose_object(struct repository *r,
256-
const struct object_id *oid,
257-
unsigned long *size)
237+
void *odb_source_loose_map_object(struct odb_source *source,
238+
const struct object_id *oid,
239+
unsigned long *size)
258240
{
259241
const char *p;
260-
int fd = open_loose_object(r, oid, &p);
242+
int fd = open_loose_object(source->loose, oid, &p);
261243

262244
if (fd < 0)
263245
return NULL;
@@ -407,9 +389,9 @@ int parse_loose_header(const char *hdr, struct object_info *oi)
407389
return 0;
408390
}
409391

410-
int loose_object_info(struct repository *r,
411-
const struct object_id *oid,
412-
struct object_info *oi, int flags)
392+
int odb_source_loose_read_object_info(struct odb_source *source,
393+
const struct object_id *oid,
394+
struct object_info *oi, int flags)
413395
{
414396
int status = 0;
415397
int fd;
@@ -422,7 +404,7 @@ int loose_object_info(struct repository *r,
422404
enum object_type type_scratch;
423405

424406
if (oi->delta_base_oid)
425-
oidclr(oi->delta_base_oid, r->hash_algo);
407+
oidclr(oi->delta_base_oid, source->odb->repo->hash_algo);
426408

427409
/*
428410
* If we don't care about type or size, then we don't
@@ -435,15 +417,15 @@ int loose_object_info(struct repository *r,
435417
if (!oi->typep && !oi->sizep && !oi->contentp) {
436418
struct stat st;
437419
if (!oi->disk_sizep && (flags & OBJECT_INFO_QUICK))
438-
return quick_has_loose(r, oid) ? 0 : -1;
439-
if (stat_loose_object(r, oid, &st, &path) < 0)
420+
return quick_has_loose(source->loose, oid) ? 0 : -1;
421+
if (stat_loose_object(source->loose, oid, &st, &path) < 0)
440422
return -1;
441423
if (oi->disk_sizep)
442424
*oi->disk_sizep = st.st_size;
443425
return 0;
444426
}
445427

446-
fd = open_loose_object(r, oid, &path);
428+
fd = open_loose_object(source->loose, oid, &path);
447429
if (fd < 0) {
448430
if (errno != ENOENT)
449431
error_errno(_("unable to open loose object %s"), oid_to_hex(oid));

object-file.h

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,14 @@ void odb_source_loose_free(struct odb_source_loose *loose);
4343
/* Reprepare the loose source by emptying the loose object cache. */
4444
void odb_source_loose_reprepare(struct odb_source *source);
4545

46+
int odb_source_loose_read_object_info(struct odb_source *source,
47+
const struct object_id *oid,
48+
struct object_info *oi, int flags);
49+
50+
void *odb_source_loose_map_object(struct odb_source *source,
51+
const struct object_id *oid,
52+
unsigned long *size);
53+
4654
/*
4755
* Populate and return the loose object cache array corresponding to the
4856
* given object ID.
@@ -66,9 +74,6 @@ const char *odb_loose_path(struct odb_source *source,
6674
int has_loose_object(struct odb_source *source,
6775
const struct object_id *oid);
6876

69-
void *map_loose_object(struct repository *r, const struct object_id *oid,
70-
unsigned long *size);
71-
7277
/*
7378
* Iterate over the files in the loose-object parts of the object
7479
* directory "path", triggering the following callbacks:
@@ -196,10 +201,6 @@ int check_object_signature(struct repository *r, const struct object_id *oid,
196201
*/
197202
int stream_object_signature(struct repository *r, const struct object_id *oid);
198203

199-
int loose_object_info(struct repository *r,
200-
const struct object_id *oid,
201-
struct object_info *oi, int flags);
202-
203204
enum finalize_object_file_flags {
204205
FOF_SKIP_COLLISION_CHECK = 1,
205206
};

odb.c

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -697,13 +697,18 @@ static int do_oid_object_info_extended(struct object_database *odb,
697697
return 0;
698698
}
699699

700+
odb_prepare_alternates(odb);
701+
700702
while (1) {
703+
struct odb_source *source;
704+
701705
if (find_pack_entry(odb->repo, real, &e))
702706
break;
703707

704708
/* Most likely it's a loose object. */
705-
if (!loose_object_info(odb->repo, real, oi, flags))
706-
return 0;
709+
for (source = odb->sources; source; source = source->next)
710+
if (!odb_source_loose_read_object_info(source, real, oi, flags))
711+
return 0;
707712

708713
/* Not a loose object; someone else may have just packed it. */
709714
if (!(flags & OBJECT_INFO_QUICK)) {

streaming.c

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -230,12 +230,21 @@ static int open_istream_loose(struct git_istream *st, struct repository *r,
230230
enum object_type *type)
231231
{
232232
struct object_info oi = OBJECT_INFO_INIT;
233+
struct odb_source *source;
234+
233235
oi.sizep = &st->size;
234236
oi.typep = type;
235237

236-
st->u.loose.mapped = map_loose_object(r, oid, &st->u.loose.mapsize);
238+
odb_prepare_alternates(r->objects);
239+
for (source = r->objects->sources; source; source = source->next) {
240+
st->u.loose.mapped = odb_source_loose_map_object(source, oid,
241+
&st->u.loose.mapsize);
242+
if (st->u.loose.mapped)
243+
break;
244+
}
237245
if (!st->u.loose.mapped)
238246
return -1;
247+
239248
switch (unpack_loose_header(&st->z, st->u.loose.mapped,
240249
st->u.loose.mapsize, st->u.loose.hdr,
241250
sizeof(st->u.loose.hdr))) {

0 commit comments

Comments
 (0)