repo: Enumerate objects using openat() too, make more efficient
This drops several calls to malloc()/g_object_new() per object enumeration. Just a followup to using openat() and friends in other places.
This commit is contained in:
parent
8592922c2c
commit
7b119370a2
|
|
@ -670,72 +670,59 @@ _ostree_repo_get_loose_object_dirs (OstreeRepo *self,
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
list_loose_object_dir (OstreeRepo *self,
|
list_loose_objects_at (OstreeRepo *self,
|
||||||
GFile *dir,
|
|
||||||
GHashTable *inout_objects,
|
GHashTable *inout_objects,
|
||||||
|
const char *prefix,
|
||||||
|
int dfd,
|
||||||
GCancellable *cancellable,
|
GCancellable *cancellable,
|
||||||
GError **error)
|
GError **error)
|
||||||
{
|
{
|
||||||
gboolean ret = FALSE;
|
gboolean ret = FALSE;
|
||||||
const char *dirname = NULL;
|
DIR *d = NULL;
|
||||||
const char *dot = NULL;
|
struct dirent *dent;
|
||||||
gs_unref_object GFileEnumerator *enumerator = NULL;
|
|
||||||
GString *checksum = NULL;
|
|
||||||
|
|
||||||
dirname = gs_file_get_basename_cached (dir);
|
d = fdopendir (dfd);
|
||||||
|
if (!d)
|
||||||
/* We're only querying name */
|
|
||||||
enumerator = g_file_enumerate_children (dir, "standard::name,standard::type",
|
|
||||||
G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
|
|
||||||
cancellable,
|
|
||||||
error);
|
|
||||||
if (!enumerator)
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
while (TRUE)
|
|
||||||
{
|
{
|
||||||
GFileInfo *file_info;
|
ot_util_set_error_from_errno (error, errno);
|
||||||
const char *name;
|
goto out;
|
||||||
guint32 type;
|
}
|
||||||
|
|
||||||
|
while ((dent = readdir (d)) != NULL)
|
||||||
|
{
|
||||||
|
const char *name = dent->d_name;
|
||||||
|
const char *dot;
|
||||||
OstreeObjectType objtype;
|
OstreeObjectType objtype;
|
||||||
|
char buf[65];
|
||||||
|
|
||||||
if (!gs_file_enumerator_iterate (enumerator, &file_info, NULL,
|
if (strcmp (name, ".") == 0 ||
|
||||||
NULL, error))
|
strcmp (name, "..") == 0)
|
||||||
goto out;
|
|
||||||
if (file_info == NULL)
|
|
||||||
break;
|
|
||||||
|
|
||||||
type = g_file_info_get_attribute_uint32 (file_info, "standard::type");
|
|
||||||
|
|
||||||
if (type == G_FILE_TYPE_DIRECTORY)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
name = g_file_info_get_attribute_byte_string (file_info, "standard::name");
|
|
||||||
|
|
||||||
if (g_str_has_suffix (name, ".file"))
|
|
||||||
objtype = OSTREE_OBJECT_TYPE_FILE;
|
|
||||||
else if (g_str_has_suffix (name, ".dirtree"))
|
|
||||||
objtype = OSTREE_OBJECT_TYPE_DIR_TREE;
|
|
||||||
else if (g_str_has_suffix (name, ".dirmeta"))
|
|
||||||
objtype = OSTREE_OBJECT_TYPE_DIR_META;
|
|
||||||
else if (g_str_has_suffix (name, ".commit"))
|
|
||||||
objtype = OSTREE_OBJECT_TYPE_COMMIT;
|
|
||||||
else
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
dot = strrchr (name, '.');
|
dot = strrchr (name, '.');
|
||||||
g_assert (dot);
|
if (!dot)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (strcmp (dot, ".file") == 0)
|
||||||
|
objtype = OSTREE_OBJECT_TYPE_FILE;
|
||||||
|
else if (strcmp (dot, ".dirtree") == 0)
|
||||||
|
objtype = OSTREE_OBJECT_TYPE_DIR_TREE;
|
||||||
|
else if (strcmp (dot, ".dirmeta") == 0)
|
||||||
|
objtype = OSTREE_OBJECT_TYPE_DIR_META;
|
||||||
|
else if (strcmp (dot, ".commit") == 0)
|
||||||
|
objtype = OSTREE_OBJECT_TYPE_COMMIT;
|
||||||
|
else
|
||||||
|
continue;
|
||||||
|
|
||||||
if ((dot - name) == 62)
|
if ((dot - name) == 62)
|
||||||
{
|
{
|
||||||
GVariant *key, *value;
|
GVariant *key, *value;
|
||||||
|
|
||||||
if (checksum)
|
memcpy (buf, prefix, 2);
|
||||||
g_string_free (checksum, TRUE);
|
memcpy (buf + 2, name, 62);
|
||||||
checksum = g_string_new (dirname);
|
buf[sizeof(buf)-1] = '\0';
|
||||||
g_string_append_len (checksum, name, 62);
|
|
||||||
|
|
||||||
key = ostree_object_name_serialize (checksum->str, objtype);
|
key = ostree_object_name_serialize (buf, objtype);
|
||||||
value = g_variant_new ("(b@as)",
|
value = g_variant_new ("(b@as)",
|
||||||
TRUE, g_variant_new_strv (NULL, 0));
|
TRUE, g_variant_new_strv (NULL, 0));
|
||||||
/* transfer ownership */
|
/* transfer ownership */
|
||||||
|
|
@ -746,8 +733,8 @@ list_loose_object_dir (OstreeRepo *self,
|
||||||
|
|
||||||
ret = TRUE;
|
ret = TRUE;
|
||||||
out:
|
out:
|
||||||
if (checksum)
|
if (d)
|
||||||
g_string_free (checksum, TRUE);
|
(void) closedir (d);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -758,16 +745,30 @@ list_loose_objects (OstreeRepo *self,
|
||||||
GError **error)
|
GError **error)
|
||||||
{
|
{
|
||||||
gboolean ret = FALSE;
|
gboolean ret = FALSE;
|
||||||
guint i;
|
guint c;
|
||||||
gs_unref_ptrarray GPtrArray *object_dirs = NULL;
|
int dfd = -1;
|
||||||
|
static const gchar hexchars[] = "0123456789abcdef";
|
||||||
|
|
||||||
if (!_ostree_repo_get_loose_object_dirs (self, &object_dirs, cancellable, error))
|
for (c = 0; c < 255; c++)
|
||||||
goto out;
|
|
||||||
|
|
||||||
for (i = 0; i < object_dirs->len; i++)
|
|
||||||
{
|
{
|
||||||
GFile *objdir = object_dirs->pdata[i];
|
char buf[3];
|
||||||
if (!list_loose_object_dir (self, objdir, inout_objects, cancellable, error))
|
buf[0] = hexchars[c >> 4];
|
||||||
|
buf[1] = hexchars[c & 0xF];
|
||||||
|
buf[2] = '\0';
|
||||||
|
dfd = openat (self->objects_dir_fd, buf, O_RDONLY | O_NONBLOCK | O_DIRECTORY | O_CLOEXEC);
|
||||||
|
if (dfd == -1)
|
||||||
|
{
|
||||||
|
if (errno == ENOENT)
|
||||||
|
continue;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ot_util_set_error_from_errno (error, errno);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* Takes ownership of dfd */
|
||||||
|
if (!list_loose_objects_at (self, inout_objects, buf, dfd,
|
||||||
|
cancellable, error))
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue