mirror of
https://github.com/git-for-windows/git.git
synced 2026-06-30 10:57:06 -05:00
odb: make backend-specific fields optional
The `struct object_info` carries two pieces of information
about how an object was looked up:
- The `whence` enum identifying the backend.
- The backend-tagged union `u` exposing backend-specific details
(currently only the packed-source case, which records the owning
pack, offset and packed object type).
The union is populated unconditionally, even though most callers don't
care about provenance at all.
Split the backend-specific union out into a new public type, `struct
object_info_source`, and make the object info structure carry it via
just another opt-in request pointer. As with all the other requestable
information, callers that need source info allocate a `struct
object_info_source` on the stack and point `sourcep` at it; callers that
don't care about it simply leave the field as a `NULL` pointer. Adapt
callers accordingly.
Note that the `whence` enum is strictly-speaking also backend-specific
information, so it would be another good candidate to be moved into the
`struct object_info_source`. For now though it is left alone, as it will
be replaced by a `struct odb_source` pointer in a subsequent commit.
Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
committed by
Junio C Hamano
parent
1b9f137b43
commit
695797490e
@@ -835,7 +835,8 @@ static int batch_one_object_oi(const struct object_id *oid,
|
||||
{
|
||||
struct for_each_object_payload *payload = _payload;
|
||||
if (oi && oi->whence == OI_PACKED)
|
||||
return payload->callback(oid, oi->u.packed.pack, oi->u.packed.offset,
|
||||
return payload->callback(oid, oi->sourcep->u.packed.pack,
|
||||
oi->sourcep->u.packed.offset,
|
||||
payload->payload);
|
||||
return payload->callback(oid, NULL, 0, payload->payload);
|
||||
}
|
||||
@@ -906,7 +907,10 @@ static void batch_each_object(struct batch_options *opt,
|
||||
&payload, flags);
|
||||
}
|
||||
} else {
|
||||
struct object_info oi = { 0 };
|
||||
struct object_info_source oi_source;
|
||||
struct object_info oi = {
|
||||
.sourcep = &oi_source,
|
||||
};
|
||||
|
||||
for (source = the_repository->objects->sources; source; source = source->next) {
|
||||
struct odb_source_files *files = odb_source_files_downcast(source);
|
||||
|
||||
@@ -1825,11 +1825,15 @@ static void repack_local_links(void)
|
||||
|
||||
oidset_iter_init(&outgoing_links, &iter);
|
||||
while ((oid = oidset_iter_next(&iter))) {
|
||||
struct object_info info = OBJECT_INFO_INIT;
|
||||
struct object_info_source info_source;
|
||||
struct object_info info = {
|
||||
.sourcep = &info_source,
|
||||
};
|
||||
|
||||
if (odb_read_object_info_extended(the_repository->objects, oid, &info, 0))
|
||||
/* Missing; assume it is a promisor object */
|
||||
continue;
|
||||
if (info.whence == OI_PACKED && info.u.packed.pack->pack_promisor)
|
||||
if (info.whence == OI_PACKED && info_source.u.packed.pack->pack_promisor)
|
||||
continue;
|
||||
|
||||
if (!cmd.args.nr) {
|
||||
|
||||
@@ -4491,8 +4491,9 @@ static int add_object_in_unpacked_pack(const struct object_id *oid,
|
||||
void *data UNUSED)
|
||||
{
|
||||
if (cruft) {
|
||||
add_cruft_object_entry(oid, OBJ_NONE, oi->u.packed.pack,
|
||||
oi->u.packed.offset, NULL, *oi->mtimep);
|
||||
add_cruft_object_entry(oid, OBJ_NONE, oi->sourcep->u.packed.pack,
|
||||
oi->sourcep->u.packed.offset, NULL,
|
||||
*oi->mtimep);
|
||||
} else {
|
||||
add_object_entry(oid, OBJ_NONE, "", 0);
|
||||
}
|
||||
@@ -4509,8 +4510,10 @@ static void add_objects_in_unpacked_packs(void)
|
||||
ODB_FOR_EACH_OBJECT_SKIP_IN_CORE_KEPT_PACKS |
|
||||
ODB_FOR_EACH_OBJECT_SKIP_ON_DISK_KEPT_PACKS,
|
||||
};
|
||||
struct object_info_source oi_source;
|
||||
struct object_info oi = {
|
||||
.mtimep = &mtime,
|
||||
.sourcep = &oi_source,
|
||||
};
|
||||
|
||||
odb_prepare_alternates(to_pack.repo->objects);
|
||||
@@ -5000,10 +5003,14 @@ static int option_parse_cruft_expiration(const struct option *opt UNUSED,
|
||||
|
||||
static int is_not_in_promisor_pack_obj(struct object *obj, void *data UNUSED)
|
||||
{
|
||||
struct object_info info = OBJECT_INFO_INIT;
|
||||
struct object_info_source info_source;
|
||||
struct object_info info = {
|
||||
.sourcep = &info_source,
|
||||
};
|
||||
|
||||
if (odb_read_object_info_extended(the_repository->objects, &obj->oid, &info, 0))
|
||||
BUG("should_include_obj should only be called on existing objects");
|
||||
return info.whence != OI_PACKED || !info.u.packed.pack->pack_promisor;
|
||||
return info.whence != OI_PACKED || !info_source.u.packed.pack->pack_promisor;
|
||||
}
|
||||
|
||||
static int is_not_in_promisor_pack(struct commit *commit, void *data) {
|
||||
|
||||
3
odb.c
3
odb.c
@@ -692,7 +692,8 @@ static int oid_object_info_convert(struct repository *r,
|
||||
}
|
||||
}
|
||||
input_oi->whence = new_oi.whence;
|
||||
input_oi->u = new_oi.u;
|
||||
if (input_oi->sourcep)
|
||||
*input_oi->sourcep = *new_oi.sourcep;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
60
odb.h
60
odb.h
@@ -248,6 +248,38 @@ int odb_pretend_object(struct object_database *odb,
|
||||
void *buf, size_t len, enum object_type type,
|
||||
struct object_id *oid);
|
||||
|
||||
/*
|
||||
* Object information that can be used to uniquely identify an object and learn
|
||||
* more about how exactly it is stored.
|
||||
*/
|
||||
struct object_info_source {
|
||||
/*
|
||||
* Backend-specific information about the specific object. This can be
|
||||
* used for example to uniquely identify a given object in case it
|
||||
* exists multiple times.
|
||||
*/
|
||||
union {
|
||||
/*
|
||||
* struct {
|
||||
* ... Nothing to expose in this case
|
||||
* } cached;
|
||||
* struct {
|
||||
* ... Nothing to expose in this case
|
||||
* } loose;
|
||||
*/
|
||||
struct {
|
||||
struct packed_git *pack;
|
||||
off_t offset;
|
||||
enum packed_object_type {
|
||||
PACKED_OBJECT_TYPE_UNKNOWN,
|
||||
PACKED_OBJECT_TYPE_FULL,
|
||||
PACKED_OBJECT_TYPE_OFS_DELTA,
|
||||
PACKED_OBJECT_TYPE_REF_DELTA,
|
||||
} type;
|
||||
} packed;
|
||||
} u;
|
||||
};
|
||||
|
||||
struct object_info {
|
||||
/* Request */
|
||||
enum object_type *typep;
|
||||
@@ -269,32 +301,20 @@ struct object_info {
|
||||
*/
|
||||
time_t *mtimep;
|
||||
|
||||
/*
|
||||
* Backend-specific information that tells the caller where exactly an
|
||||
* object was looked up from. This information should help disambiguate
|
||||
* object lookups in case the same object exists in multiple sources,
|
||||
* or multiple times in the same source.
|
||||
*/
|
||||
struct object_info_source *sourcep;
|
||||
|
||||
/* Response */
|
||||
enum {
|
||||
OI_CACHED,
|
||||
OI_LOOSE,
|
||||
OI_PACKED,
|
||||
} whence;
|
||||
union {
|
||||
/*
|
||||
* struct {
|
||||
* ... Nothing to expose in this case
|
||||
* } cached;
|
||||
* struct {
|
||||
* ... Nothing to expose in this case
|
||||
* } loose;
|
||||
*/
|
||||
struct {
|
||||
struct packed_git *pack;
|
||||
off_t offset;
|
||||
enum packed_object_type {
|
||||
PACKED_OBJECT_TYPE_UNKNOWN,
|
||||
PACKED_OBJECT_TYPE_FULL,
|
||||
PACKED_OBJECT_TYPE_OFS_DELTA,
|
||||
PACKED_OBJECT_TYPE_REF_DELTA,
|
||||
} type;
|
||||
} packed;
|
||||
} u;
|
||||
};
|
||||
|
||||
/*
|
||||
|
||||
33
packfile.c
33
packfile.c
@@ -1422,22 +1422,25 @@ int packed_object_info_with_index_pos(struct odb_source_packed *source UNUSED,
|
||||
}
|
||||
|
||||
oi->whence = OI_PACKED;
|
||||
oi->u.packed.offset = obj_offset;
|
||||
oi->u.packed.pack = p;
|
||||
|
||||
switch (type) {
|
||||
case OBJ_NONE:
|
||||
oi->u.packed.type = PACKED_OBJECT_TYPE_UNKNOWN;
|
||||
break;
|
||||
case OBJ_REF_DELTA:
|
||||
oi->u.packed.type = PACKED_OBJECT_TYPE_REF_DELTA;
|
||||
break;
|
||||
case OBJ_OFS_DELTA:
|
||||
oi->u.packed.type = PACKED_OBJECT_TYPE_OFS_DELTA;
|
||||
break;
|
||||
default:
|
||||
oi->u.packed.type = PACKED_OBJECT_TYPE_FULL;
|
||||
break;
|
||||
if (oi->sourcep) {
|
||||
oi->sourcep->u.packed.offset = obj_offset;
|
||||
oi->sourcep->u.packed.pack = p;
|
||||
|
||||
switch (type) {
|
||||
case OBJ_NONE:
|
||||
oi->sourcep->u.packed.type = PACKED_OBJECT_TYPE_UNKNOWN;
|
||||
break;
|
||||
case OBJ_REF_DELTA:
|
||||
oi->sourcep->u.packed.type = PACKED_OBJECT_TYPE_REF_DELTA;
|
||||
break;
|
||||
case OBJ_OFS_DELTA:
|
||||
oi->sourcep->u.packed.type = PACKED_OBJECT_TYPE_OFS_DELTA;
|
||||
break;
|
||||
default:
|
||||
oi->sourcep->u.packed.type = PACKED_OBJECT_TYPE_FULL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
|
||||
@@ -235,7 +235,8 @@ static int add_recent_object(const struct object_id *oid,
|
||||
add_pending_object(data->revs, obj, "");
|
||||
if (data->cb) {
|
||||
if (oi->whence == OI_PACKED)
|
||||
data->cb(obj, oi->u.packed.pack, oi->u.packed.offset, *oi->mtimep);
|
||||
data->cb(obj, oi->sourcep->u.packed.pack,
|
||||
oi->sourcep->u.packed.offset, *oi->mtimep);
|
||||
else
|
||||
data->cb(obj, NULL, 0, *oi->mtimep);
|
||||
}
|
||||
@@ -252,9 +253,11 @@ int add_unseen_recent_objects_to_traversal(struct rev_info *revs,
|
||||
unsigned flags;
|
||||
enum object_type type;
|
||||
time_t mtime;
|
||||
struct object_info_source oi_source;
|
||||
struct object_info oi = {
|
||||
.mtimep = &mtime,
|
||||
.typep = &type,
|
||||
.sourcep = &oi_source,
|
||||
};
|
||||
int r;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user