commit - 4c4ce67b628a0b29afb50487072e667ee37e1dad
commit + 7b5b670e542e9a69edcd9c3d76ce9ab4a3855c6f
blob - 5f2594f5af806ea9b99c358f35fa4e7ce16f7efb
blob + 8a7ddd1fed280c5ace7be5e759d1b7ef2c6cc784
--- include/got_reference.h
+++ include/got_reference.h
/* Unlock a reference which was opened in locked state. */
const struct got_error *got_ref_unlock(struct got_reference *);
+
+/* Map object IDs to references. */
+struct got_reflist_object_id_map;
+
+/*
+ * Create and populate an object ID map for a given list of references.
+ * Map entries will contain deep-copies of elements of the reflist.
+ * The caller must dispose of the map with got_reflist_object_map_free().
+ */
+const struct got_error *got_reflist_object_id_map_create(
+ struct got_reflist_object_id_map **, struct got_reflist_head *,
+ struct got_repository *);
+
+/*
+ * Return a list of references which correspond to a given object ID.
+ * The returned list must be considered read-only.
+ * The caller must _not_ call free(3) on the returned pointer!
+ * If no references are associated with the ID, return NULL.
+ */
+struct got_reflist_head *
+got_reflist_object_id_map_lookup(struct got_reflist_object_id_map *,
+ struct got_object_id *);
+
+/* Free the specified object ID map. */
+void got_reflist_object_map_free(struct got_reflist_object_id_map *);
blob - 7df07c953f7657dda28101ec2213bf5c222db220
blob + d9f1596591be3332b0a51e1ec4e6c77a90720fae
--- lib/reference.c
+++ lib/reference.c
#include "got_lib_delta.h"
#include "got_lib_inflate.h"
#include "got_lib_object.h"
+#include "got_lib_object_idset.h"
#include "got_lib_lockfile.h"
#ifndef nitems
ref->lf = NULL;
return err;
}
+
+struct got_reflist_object_id_map {
+ struct got_object_idset *idset;
+};
+
+struct got_reflist_object_id_map_entry {
+ struct got_reflist_head refs;
+};
+
+const struct got_error *
+got_reflist_object_id_map_create(struct got_reflist_object_id_map **map,
+ struct got_reflist_head *refs, struct got_repository *repo)
+{
+ const struct got_error *err = NULL;
+ struct got_object_idset *idset;
+ struct got_object_id *id = NULL;
+ struct got_reflist_entry *re;
+
+ idset = got_object_idset_alloc();
+ if (idset == NULL)
+ return got_error_from_errno("got_object_idset_alloc");
+
+ *map = malloc(sizeof(**map));
+ if (*map == NULL) {
+ got_object_idset_free(idset);
+ return got_error_from_errno("malloc");
+ }
+ (*map)->idset = idset;
+
+ SIMPLEQ_FOREACH(re, refs, entry) {
+ struct got_reflist_entry *new;
+ struct got_reflist_object_id_map_entry *ent;
+
+ err = got_ref_resolve(&id, repo, re->ref);
+ if (err)
+ goto done;
+
+ ent = got_object_idset_get(idset, id);
+ if (ent == NULL) {
+ ent = malloc(sizeof(*ent));
+ if (ent == NULL) {
+ err = got_error_from_errno("malloc");
+ goto done;
+ }
+ SIMPLEQ_INIT(&ent->refs);
+ err = got_object_idset_add(idset, id, ent);
+ if (err)
+ goto done;
+ }
+
+ err = got_reflist_entry_dup(&new, re);
+ if (err)
+ goto done;
+ SIMPLEQ_INSERT_TAIL(&ent->refs, new, entry);
+ free(id);
+ id = NULL;
+ }
+done:
+ free(id);
+ if (err) {
+ got_reflist_object_map_free(*map);
+ *map = NULL;
+ }
+ return NULL;
+}
+
+struct got_reflist_head *
+got_reflist_object_id_map_lookup(struct got_reflist_object_id_map *map,
+ struct got_object_id *id)
+{
+ struct got_reflist_object_id_map_entry *ent;
+ ent = got_object_idset_get(map->idset, id);
+ if (ent)
+ return &ent->refs;
+ return NULL;
+}
+
+static const struct got_error *
+free_id_map_entry(struct got_object_id *id, void *data, void *arg)
+{
+ struct got_reflist_object_id_map_entry *ent = data;
+
+ got_ref_list_free(&ent->refs);
+ free(ent);
+ return NULL;
+}
+
+void
+got_reflist_object_map_free(struct got_reflist_object_id_map *map)
+{
+ got_object_idset_for_each(map->idset, free_id_map_entry, NULL);
+ got_object_idset_free(map->idset);
+ free(map);
+}