Merge branch 'ps/odb-drop-whence' into next
The 'whence' field in 'struct object_info' has been removed, refactoring backend-specific object information retrieval into an opt- in 'struct object_info_source' structure. * ps/odb-drop-whence: odb: document object info fields odb: drop `whence` field from object info treewide: convert users of `whence` to the new source field odb: add `source` field to struct object_info_source odb: make backend-specific fields optional packfile: thread odb_source_packed through packed_object_info()next
commit
f43ee51cc3
|
|
@ -500,7 +500,7 @@ static void batch_object_write(const char *obj_name,
|
|||
data->info.sizep = &data->size;
|
||||
|
||||
if (pack)
|
||||
ret = packed_object_info(pack, offset, &data->info);
|
||||
ret = packed_object_info(NULL, pack, offset, &data->info);
|
||||
else
|
||||
ret = odb_read_object_info_extended(the_repository->objects,
|
||||
&data->oid, &data->info,
|
||||
|
|
@ -837,8 +837,9 @@ static int batch_one_object_oi(const struct object_id *oid,
|
|||
void *_payload)
|
||||
{
|
||||
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,
|
||||
if (oi && oi->source_infop->source->type == ODB_SOURCE_PACKED)
|
||||
return payload->callback(oid, oi->source_infop->u.packed.pack,
|
||||
oi->source_infop->u.packed.offset,
|
||||
payload->payload);
|
||||
return payload->callback(oid, NULL, 0, payload->payload);
|
||||
}
|
||||
|
|
@ -909,7 +910,10 @@ static void batch_each_object(struct batch_options *opt,
|
|||
&payload, flags);
|
||||
}
|
||||
} else {
|
||||
struct object_info oi = { 0 };
|
||||
struct odb_source_info source_info;
|
||||
struct object_info oi = {
|
||||
.source_infop = &source_info,
|
||||
};
|
||||
|
||||
for (source = the_repository->objects->sources; source; source = source->next) {
|
||||
struct odb_source_files *files = odb_source_files_downcast(source);
|
||||
|
|
|
|||
|
|
@ -1825,11 +1825,16 @@ 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 odb_source_info source_info;
|
||||
struct object_info info = {
|
||||
.source_infop = &source_info,
|
||||
};
|
||||
|
||||
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 (source_info.source->type == ODB_SOURCE_PACKED &&
|
||||
source_info.u.packed.pack->pack_promisor)
|
||||
continue;
|
||||
|
||||
if (!cmd.args.nr) {
|
||||
|
|
|
|||
|
|
@ -2463,7 +2463,7 @@ static void drop_reused_delta(struct object_entry *entry)
|
|||
|
||||
oi.sizep = &size;
|
||||
oi.typep = &type;
|
||||
if (packed_object_info(IN_PACK(entry), entry->in_pack_offset, &oi) < 0) {
|
||||
if (packed_object_info(NULL, IN_PACK(entry), entry->in_pack_offset, &oi) < 0) {
|
||||
/*
|
||||
* We failed to get the info from this pack for some reason;
|
||||
* fall back to odb_read_object_info, which may find another copy.
|
||||
|
|
@ -3820,7 +3820,7 @@ static int add_object_entry_from_pack(const struct object_id *oid,
|
|||
ofs = nth_packed_object_offset(p, pos);
|
||||
|
||||
oi.typep = &type;
|
||||
if (packed_object_info(p, ofs, &oi) < 0) {
|
||||
if (packed_object_info(NULL, p, ofs, &oi) < 0) {
|
||||
die(_("could not get type of object %s in pack %s"),
|
||||
oid_to_hex(oid), p->pack_name);
|
||||
} else if (type == OBJ_COMMIT) {
|
||||
|
|
@ -4495,8 +4495,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->source_infop->u.packed.pack,
|
||||
oi->source_infop->u.packed.offset, NULL,
|
||||
*oi->mtimep);
|
||||
} else {
|
||||
add_object_entry(oid, OBJ_NONE, "", 0);
|
||||
}
|
||||
|
|
@ -4513,8 +4514,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 odb_source_info source_info;
|
||||
struct object_info oi = {
|
||||
.mtimep = &mtime,
|
||||
.source_infop = &source_info,
|
||||
};
|
||||
|
||||
odb_prepare_alternates(to_pack.repo->objects);
|
||||
|
|
@ -5036,10 +5039,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 odb_source_info source_info;
|
||||
struct object_info info = {
|
||||
.source_infop = &source_info,
|
||||
};
|
||||
|
||||
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 source_info.source->type != ODB_SOURCE_PACKED || !source_info.u.packed.pack->pack_promisor;
|
||||
}
|
||||
|
||||
static int is_not_in_promisor_pack(struct commit *commit, void *data) {
|
||||
|
|
|
|||
|
|
@ -1538,7 +1538,7 @@ static int add_packed_commits(const struct object_id *oid,
|
|||
struct object_info oi = OBJECT_INFO_INIT;
|
||||
|
||||
oi.typep = &type;
|
||||
if (packed_object_info(pack, offset, &oi) < 0)
|
||||
if (packed_object_info(NULL, pack, offset, &oi) < 0)
|
||||
die(_("unable to get type of object %s"), oid_to_hex(oid));
|
||||
|
||||
return add_packed_commits_oi(oid, &oi, data);
|
||||
|
|
|
|||
4
odb.c
4
odb.c
|
|
@ -691,8 +691,8 @@ static int oid_object_info_convert(struct repository *r,
|
|||
return -1;
|
||||
}
|
||||
}
|
||||
input_oi->whence = new_oi.whence;
|
||||
input_oi->u = new_oi.u;
|
||||
if (input_oi->source_infop)
|
||||
*input_oi->source_infop = *new_oi.source_infop;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
|||
80
odb.h
80
odb.h
|
|
@ -260,33 +260,19 @@ int odb_pretend_object(struct object_database *odb,
|
|||
void *buf, size_t len, enum object_type type,
|
||||
struct object_id *oid);
|
||||
|
||||
struct object_info {
|
||||
/* Request */
|
||||
enum object_type *typep;
|
||||
size_t *sizep;
|
||||
off_t *disk_sizep;
|
||||
struct object_id *delta_base_oid;
|
||||
void **contentp;
|
||||
/*
|
||||
* Object database source information that can be used to uniquely identify an
|
||||
* object and learn more about how exactly it is stored.
|
||||
*/
|
||||
struct odb_source_info {
|
||||
/* The source that this object has been looked up from. */
|
||||
struct odb_source *source;
|
||||
|
||||
/*
|
||||
* The time the given looked-up object has been last modified.
|
||||
*
|
||||
* Note: the mtime may be ambiguous in case the object exists multiple
|
||||
* times in the object database. It is thus _not_ recommended to use
|
||||
* this field outside of contexts where you would read every instance
|
||||
* of the object, like for example with `odb_for_each_object()`. As it
|
||||
* is impossible to say at the ODB level what the intent of the caller
|
||||
* is (e.g. whether to find the oldest or newest object), it is the
|
||||
* responsibility of the caller to disambiguate the mtimes.
|
||||
* 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.
|
||||
*/
|
||||
time_t *mtimep;
|
||||
|
||||
/* Response */
|
||||
enum {
|
||||
OI_CACHED,
|
||||
OI_LOOSE,
|
||||
OI_PACKED,
|
||||
} whence;
|
||||
union {
|
||||
/*
|
||||
* struct {
|
||||
|
|
@ -309,6 +295,52 @@ struct object_info {
|
|||
} u;
|
||||
};
|
||||
|
||||
/*
|
||||
* The object info contains the query and response that is to be used for
|
||||
* functions that end up reading object information. Callers are expected to
|
||||
* populate pointers whose information they want to request.
|
||||
*/
|
||||
struct object_info {
|
||||
/* The object type. */
|
||||
enum object_type *typep;
|
||||
|
||||
/* The inflated object size in bytes. */
|
||||
size_t *sizep;
|
||||
|
||||
/* The object size as stored on disk. */
|
||||
off_t *disk_sizep;
|
||||
|
||||
/*
|
||||
* The base the object is deltified against, in case it is stored as a
|
||||
* delta.
|
||||
*/
|
||||
struct object_id *delta_base_oid;
|
||||
|
||||
/* The object contents. Ownership of memory goes over to the caller. */
|
||||
void **contentp;
|
||||
|
||||
/*
|
||||
* The time the given looked-up object has been last modified.
|
||||
*
|
||||
* Note: the mtime may be ambiguous in case the object exists multiple
|
||||
* times in the object database. It is thus _not_ recommended to use
|
||||
* this field outside of contexts where you would read every instance
|
||||
* of the object, like for example with `odb_for_each_object()`. As it
|
||||
* is impossible to say at the ODB level what the intent of the caller
|
||||
* is (e.g. whether to find the oldest or newest object), it is the
|
||||
* responsibility of the caller to disambiguate the mtimes.
|
||||
*/
|
||||
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 odb_source_info *source_infop;
|
||||
};
|
||||
|
||||
/*
|
||||
* Initializer for a "struct object_info" that wants no items. You may
|
||||
* also memset() the memory to all-zeroes.
|
||||
|
|
|
|||
|
|
@ -52,7 +52,8 @@ static void populate_object_info(struct odb_source_inmemory *source,
|
|||
*oi->contentp = xmemdupz(object->buf, object->size);
|
||||
if (oi->mtimep)
|
||||
*oi->mtimep = 0;
|
||||
oi->whence = OI_CACHED;
|
||||
if (oi->source_infop)
|
||||
oi->source_infop->source = &source->base;
|
||||
}
|
||||
|
||||
static int odb_source_inmemory_read_object_info(struct odb_source *source,
|
||||
|
|
|
|||
|
|
@ -196,8 +196,8 @@ out:
|
|||
oi->typep = NULL;
|
||||
if (oi->delta_base_oid)
|
||||
oidclr(oi->delta_base_oid, loose->base.odb->repo->hash_algo);
|
||||
if (!ret)
|
||||
oi->whence = OI_LOOSE;
|
||||
if (oi->source_infop && !ret)
|
||||
oi->source_infop->source = &loose->base;
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
|
|
|||
|
|
@ -59,7 +59,7 @@ static int odb_source_packed_read_object_info(struct odb_source *source,
|
|||
if (!oi)
|
||||
return 0;
|
||||
|
||||
ret = packed_object_info(e.p, e.offset, oi);
|
||||
ret = packed_object_info(packed, e.p, e.offset, oi);
|
||||
if (ret < 0) {
|
||||
mark_bad_packed_object(e.p, oid);
|
||||
return -1;
|
||||
|
|
@ -99,7 +99,7 @@ static int odb_source_packed_for_each_object_wrapper(const struct object_id *oid
|
|||
off_t offset = nth_packed_object_offset(pack, index_pos);
|
||||
struct object_info oi = *data->request;
|
||||
|
||||
if (packed_object_info_with_index_pos(pack, offset,
|
||||
if (packed_object_info_with_index_pos(data->store, pack, offset,
|
||||
&index_pos, &oi) < 0) {
|
||||
mark_bad_packed_object(pack, oid);
|
||||
return -1;
|
||||
|
|
|
|||
|
|
@ -1877,7 +1877,7 @@ static unsigned long get_size_by_pos(struct bitmap_index *bitmap_git,
|
|||
ofs = pack_pos_to_offset(pack, pos);
|
||||
}
|
||||
|
||||
if (packed_object_info(pack, ofs, &oi) < 0) {
|
||||
if (packed_object_info(NULL, pack, ofs, &oi) < 0) {
|
||||
struct object_id oid;
|
||||
nth_bitmap_object_oid(bitmap_git, &oid,
|
||||
pack_pos_to_index(pack, pos));
|
||||
|
|
|
|||
45
packfile.c
45
packfile.c
|
|
@ -1324,7 +1324,8 @@ static void add_delta_base_cache(struct packed_git *p, off_t base_offset,
|
|||
hashmap_add(&delta_base_cache, &ent->ent);
|
||||
}
|
||||
|
||||
int packed_object_info_with_index_pos(struct packed_git *p, off_t obj_offset,
|
||||
int packed_object_info_with_index_pos(struct odb_source_packed *source,
|
||||
struct packed_git *p, off_t obj_offset,
|
||||
uint32_t *maybe_index_pos, struct object_info *oi)
|
||||
{
|
||||
struct pack_window *w_curs = NULL;
|
||||
|
|
@ -1420,23 +1421,28 @@ int packed_object_info_with_index_pos(struct packed_git *p, off_t obj_offset,
|
|||
oidclr(oi->delta_base_oid, p->repo->hash_algo);
|
||||
}
|
||||
|
||||
oi->whence = OI_PACKED;
|
||||
oi->u.packed.offset = obj_offset;
|
||||
oi->u.packed.pack = p;
|
||||
if (oi->source_infop) {
|
||||
if (!source)
|
||||
BUG("cannot request source without an owning source");
|
||||
oi->source_infop->source = &source->base;
|
||||
|
||||
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;
|
||||
oi->source_infop->u.packed.offset = obj_offset;
|
||||
oi->source_infop->u.packed.pack = p;
|
||||
|
||||
switch (type) {
|
||||
case OBJ_NONE:
|
||||
oi->source_infop->u.packed.type = PACKED_OBJECT_TYPE_UNKNOWN;
|
||||
break;
|
||||
case OBJ_REF_DELTA:
|
||||
oi->source_infop->u.packed.type = PACKED_OBJECT_TYPE_REF_DELTA;
|
||||
break;
|
||||
case OBJ_OFS_DELTA:
|
||||
oi->source_infop->u.packed.type = PACKED_OBJECT_TYPE_OFS_DELTA;
|
||||
break;
|
||||
default:
|
||||
oi->source_infop->u.packed.type = PACKED_OBJECT_TYPE_FULL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
|
|
@ -1446,10 +1452,11 @@ out:
|
|||
return ret;
|
||||
}
|
||||
|
||||
int packed_object_info(struct packed_git *p, off_t obj_offset,
|
||||
int packed_object_info(struct odb_source_packed *source,
|
||||
struct packed_git *p, off_t obj_offset,
|
||||
struct object_info *oi)
|
||||
{
|
||||
return packed_object_info_with_index_pos(p, obj_offset, NULL, oi);
|
||||
return packed_object_info_with_index_pos(source, p, obj_offset, NULL, oi);
|
||||
}
|
||||
|
||||
static void *unpack_compressed_entry(struct packed_git *p,
|
||||
|
|
|
|||
|
|
@ -320,9 +320,11 @@ extern int do_check_packed_object_crc;
|
|||
* Look up the object info for a specific offset in the packfile.
|
||||
* Returns zero on success, a negative error code otherwise.
|
||||
*/
|
||||
int packed_object_info(struct packed_git *pack,
|
||||
int packed_object_info(struct odb_source_packed *source,
|
||||
struct packed_git *pack,
|
||||
off_t offset, struct object_info *);
|
||||
int packed_object_info_with_index_pos(struct packed_git *p, off_t obj_offset,
|
||||
int packed_object_info_with_index_pos(struct odb_source_packed *source,
|
||||
struct packed_git *p, off_t obj_offset,
|
||||
uint32_t *maybe_index_pos, struct object_info *oi);
|
||||
|
||||
void mark_bad_packed_object(struct packed_git *, const struct object_id *);
|
||||
|
|
|
|||
|
|
@ -234,8 +234,9 @@ 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);
|
||||
if (oi->source_infop->source->type == ODB_SOURCE_PACKED)
|
||||
data->cb(obj, oi->source_infop->u.packed.pack,
|
||||
oi->source_infop->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 odb_source_info source_info;
|
||||
struct object_info oi = {
|
||||
.mtimep = &mtime,
|
||||
.typep = &type,
|
||||
.source_infop = &source_info,
|
||||
};
|
||||
int r;
|
||||
|
||||
|
|
|
|||
|
|
@ -52,7 +52,7 @@ static int add_packed_object(const struct object_id *oid,
|
|||
|
||||
entry = packlist_alloc(packed, oid);
|
||||
entry->idx.offset = nth_packed_object_offset(pack, pos);
|
||||
if (packed_object_info(pack, entry->idx.offset, &oi) < 0)
|
||||
if (packed_object_info(NULL, pack, entry->idx.offset, &oi) < 0)
|
||||
die("could not get type of object %s",
|
||||
oid_to_hex(oid));
|
||||
oe_set_type(entry, type);
|
||||
|
|
|
|||
Loading…
Reference in New Issue