[virt-tools-list] [PATCH 31/47] Turn OS relationships into a GList structure
Daniel P. Berrange
berrange at redhat.com
Wed Aug 25 19:37:26 UTC 2010
Simplify storage of OS relationships by using a single GList
instead of a pair of GTree objects. The data access patterns
mean there is no change in access efficiency
* osinfo/osinfo_common.h, osinfo/osinfo_dataread.c,
osinfo/osinfo_db.c, osinfo/osinfo_entity.c,
osinfo/osinfo_os.c, osinfo/osinfo_os.h: Replace
GTree with GList for OS relationships.
---
osinfo/osinfo_common.h | 20 +-----
osinfo/osinfo_dataread.c | 61 ++++---------------
osinfo/osinfo_db.c | 9 ++-
osinfo/osinfo_entity.c | 26 +++++---
osinfo/osinfo_os.c | 149 ++++++++++------------------------------------
osinfo/osinfo_os.h | 2 +
6 files changed, 69 insertions(+), 198 deletions(-)
diff --git a/osinfo/osinfo_common.h b/osinfo/osinfo_common.h
index c660a73..dcfa109 100644
--- a/osinfo/osinfo_common.h
+++ b/osinfo/osinfo_common.h
@@ -42,14 +42,13 @@ struct __osinfoDeviceLink {
};
struct __osinfoOsLink {
- /* <subject_os> 'verbs' <direct_object_os>
+ /* <self> 'verbs' <other_os>
* fedora11 upgrades fedora10
* centos clones rhel
* scientificlinux derives from rhel
*/
- OsinfoOs *subjectOs;
- osinfoRelationship verb;
- OsinfoOs *directObjectOs;
+ osinfoRelationship relshp;
+ OsinfoOs *otherOs;
};
struct __osinfoOsCheckRelationshipArgs {
@@ -103,13 +102,8 @@ struct _OsinfoOsPrivate
// Value: List of device_link structs
GList *deviceLinks;
- // OS-OS relationships
- // Key: gchar* (other os id)
- // Value: Array of os_link structs
- GTree *relationshipsByOs;
- // Key: relationship type
// Value: Array of os_link structs
- GTree *relationshipsByType;
+ GList *osLinks;
};
struct _OsinfoEntityPrivate
@@ -121,11 +115,5 @@ struct _OsinfoEntityPrivate
GTree *params;
};
-/** ****************************************************************************
- * Private Methods
- ******************************************************************************/
-
-int __osinfoAddOsRelationship (OsinfoOs *self, gchar *otherOsId, osinfoRelationship rel);
-void __osinfoClearOsRelationships (OsinfoOs *self, gchar *otherOsId);
#endif /* __OSINFO_OBJECTS_H__ */
diff --git a/osinfo/osinfo_dataread.c b/osinfo/osinfo_dataread.c
index 9d92c49..3e6231d 100644
--- a/osinfo/osinfo_dataread.c
+++ b/osinfo/osinfo_dataread.c
@@ -43,49 +43,6 @@ struct __osinfoDbRet {
g_set_error_literal((err), g_quark_from_static_string("libosinfo"), 0, (msg));
-static gboolean __osinfoResolveOsLink(gpointer key, gpointer value, gpointer data)
-{
- gchar *targetOsId = (gchar *) key;
- struct __osinfoDbRet *dbRet = (struct __osinfoDbRet *) data;
- OsinfoDb *db = dbRet->db;
- struct __osinfoOsLink *osLink = (struct __osinfoOsLink *) value;
- OsinfoOs *targetOs;
- OsinfoOsList *oslist = osinfo_db_get_os_list(db);
-
- targetOs = OSINFO_OS(osinfo_list_find_by_id(OSINFO_LIST(oslist), targetOsId));
- if (!targetOs) {
- OSINFO_ERROR(dbRet->err, "missing os");
- return TRUE;
- }
-
- osLink->directObjectOs = targetOs;
- return FALSE;
-}
-
-static gboolean __osinfoFixOsLinks(OsinfoList *list, OsinfoEntity *entity, gpointer data)
-{
- g_return_val_if_fail(OSINFO_OS(entity), TRUE);
-
- struct __osinfoDbRet *dbRet = data;
- OsinfoOs *os = OSINFO_OS(entity);
-
- g_tree_foreach(os->priv->relationshipsByOs, __osinfoResolveOsLink, dbRet);
- if (*dbRet->err)
- return TRUE;
-
- return FALSE;
-}
-
-static void __osinfoFixObjLinks(OsinfoDb *db, GError **err)
-{
- g_return_if_fail(OSINFO_IS_DB(db));
-
- struct __osinfoDbRet dbRet = {db, err };
- OsinfoOsList *oses = osinfo_db_get_os_list(db);
-
- osinfo_list_foreach(OSINFO_LIST(oses), __osinfoFixOsLinks, &dbRet);
-}
-
static int __osinfoProcessTag(xmlTextReaderPtr reader, char** ptr_to_key, char** ptr_to_val)
{
int node_type, ret, err = 0;
@@ -246,6 +203,7 @@ error:
}
static int __osinfoProcessOsRelationship(xmlTextReaderPtr reader,
+ OsinfoDb *db,
OsinfoOs *os,
osinfoRelationship relationship)
{
@@ -259,9 +217,14 @@ static int __osinfoProcessOsRelationship(xmlTextReaderPtr reader,
return -EINVAL;
}
- ret = __osinfoAddOsRelationship (os, id, relationship);
+ OsinfoOs *otheros = osinfo_db_get_os(db, id);
+ if (!otheros) {
+ free(id);
+ return -ENOENT;
+ }
+ osinfo_os_add_related_os(os, relationship, otheros);
free(id);
- return ret;
+ return 0;
}
static int __osinfoProcessOs(OsinfoDb *db,
@@ -367,17 +330,17 @@ static int __osinfoProcessOs(OsinfoDb *db,
goto cleanup_error;
}
else if (strcmp(name, "upgrades") == 0) {
- err = __osinfoProcessOsRelationship(reader, os, UPGRADES);
+ err = __osinfoProcessOsRelationship(reader, db, os, UPGRADES);
if (err != 0)
goto cleanup_error;
}
else if (strcmp(name, "clones") == 0) {
- err = __osinfoProcessOsRelationship(reader, os, CLONES);
+ err = __osinfoProcessOsRelationship(reader, db, os, CLONES);
if (err != 0)
goto cleanup_error;
}
else if (strcmp(name, "derives-from") == 0) {
- err = __osinfoProcessOsRelationship(reader, os, DERIVES_FROM);
+ err = __osinfoProcessOsRelationship(reader, db, os, DERIVES_FROM);
if (err != 0)
goto cleanup_error;
}
@@ -784,8 +747,6 @@ void osinfo_dataread(OsinfoDb *db, GError **err)
break;
}
closedir(dir);
- if (!*err)
- __osinfoFixObjLinks(db, err);
cleanup:
xmlCleanupParser();
diff --git a/osinfo/osinfo_db.c b/osinfo/osinfo_db.c
index 2a5740f..09ba57a 100644
--- a/osinfo/osinfo_db.c
+++ b/osinfo/osinfo_db.c
@@ -288,11 +288,12 @@ static gboolean __osinfoAddOsIfRelationship(OsinfoList *list, OsinfoEntity *enti
struct __osinfoOsCheckRelationshipArgs *args = data;
OsinfoOs *os = OSINFO_OS(entity);
OsinfoList *newList = args->list;
+ OsinfoOsList *thisList = osinfo_os_get_related(os, args->relshp);
+ int i;
- GPtrArray *relatedOses = NULL;
- relatedOses = g_tree_lookup(os->priv->relationshipsByType, (gpointer) args->relshp);
- if (relatedOses) {
- osinfo_list_add(newList, OSINFO_ENTITY (os));
+ for (i = 0 ; i < osinfo_list_get_length(OSINFO_LIST(thisList)) ; i++) {
+ OsinfoEntity *entity = osinfo_list_get_nth(OSINFO_LIST(thisList), i);
+ osinfo_list_add(newList, entity);
}
return FALSE;
diff --git a/osinfo/osinfo_entity.c b/osinfo/osinfo_entity.c
index da48489..8df1de5 100644
--- a/osinfo/osinfo_entity.c
+++ b/osinfo/osinfo_entity.c
@@ -252,30 +252,36 @@ static gboolean osinfo_entity_relation_matcher(OsinfoFilter *self,
gpointer data)
{
OsinfoOs *os = data;
- GPtrArray *osOses;
+ OsinfoOsList *oslist = osinfo_os_get_related(os, relshp);
+ gboolean ret = TRUE;
- osOses = g_tree_lookup(os->priv->relationshipsByType, GINT_TO_POINTER(relshp));
- if (relOses && !osOses)
- return FALSE;
+ if (relOses && osinfo_list_get_length(OSINFO_LIST(oslist)) == 0) {
+ ret = FALSE;
+ goto cleanup;
+ }
while (relOses) {
OsinfoOs *currOs = relOses->data;
- int j;
+ int i;
gboolean found = FALSE;
- for (j = 0; j < osOses->len; j++) {
- OsinfoOs *testOs = g_ptr_array_index(osOses, j);
+ for (i = 0 ; i < osinfo_list_get_length(OSINFO_LIST(oslist)) ; i++) {
+ OsinfoOs *testOs = OSINFO_OS(osinfo_list_get_nth(OSINFO_LIST(oslist), i));
if (testOs == currOs) {
found = TRUE;
break;
}
}
- if (!found)
- return FALSE;
+ if (!found) {
+ ret = FALSE;
+ goto cleanup;
+ }
relOses = relOses->next;
}
- return TRUE;
+ cleanup:
+ g_object_unref(oslist);
+ return ret;
}
diff --git a/osinfo/osinfo_os.c b/osinfo/osinfo_os.c
index dc27c6d..5842a12 100644
--- a/osinfo/osinfo_os.c
+++ b/osinfo/osinfo_os.c
@@ -11,6 +11,11 @@ static void osinfo_device_link_free(gpointer data, gpointer opaque G_GNUC_UNUSED
__osinfoFreeDeviceLink(data);
}
+static void osinfo_os_link_free(gpointer data, gpointer opaque G_GNUC_UNUSED)
+{
+ __osinfoFreeOsLink(data);
+}
+
static void
osinfo_os_finalize (GObject *object)
@@ -20,8 +25,9 @@ osinfo_os_finalize (GObject *object)
g_list_foreach(self->priv->deviceLinks, osinfo_device_link_free, NULL);
g_list_free(self->priv->deviceLinks);
g_hash_table_unref(self->priv->hypervisors);
- g_tree_destroy (self->priv->relationshipsByOs);
- g_tree_destroy (self->priv->relationshipsByType);
+
+ g_list_foreach(self->priv->osLinks, osinfo_os_link_free, NULL);
+ g_list_free(self->priv->osLinks);
/* Chain up to the parent class */
G_OBJECT_CLASS (osinfo_os_parent_class)->finalize (object);
@@ -53,13 +59,7 @@ osinfo_os_init (OsinfoOs *self)
self->priv = priv = OSINFO_OS_GET_PRIVATE(self);
self->priv->deviceLinks = NULL;
-
- self->priv->relationshipsByOs = g_tree_new_full(__osinfoStringCompare,
- NULL,
- g_free,
- __osinfoFreeRelationship);
- self->priv->relationshipsByType = g_tree_new(__osinfoIntCompareBase);
-
+ self->priv->osLinks = NULL;
self->priv->hypervisors = g_hash_table_new_full(g_str_hash,
g_str_equal,
g_free,
@@ -74,106 +74,6 @@ OsinfoOs *osinfo_os_new(const gchar *id)
}
-static int __osinfoAddOsRelationshipByOs(OsinfoOs *self,
- gchar *otherOsId,
- osinfoRelationship rel,
- struct __osinfoOsLink *osLink)
-{
- gboolean found;
- gpointer origKey, foundValue;
- GPtrArray *relationshipsForOs;
- gchar *otherOsIdDup = NULL;
-
- found = g_tree_lookup_extended(self->priv->relationshipsByOs, otherOsId, &origKey, &foundValue);
- if (!found) {
- otherOsIdDup = g_strdup(otherOsId);
- relationshipsForOs = g_ptr_array_new_with_free_func(__osinfoFreeOsLink);
-
- g_tree_insert(self->priv->relationshipsByOs, otherOsIdDup, relationshipsForOs);
- }
- else
- relationshipsForOs = (GPtrArray *) foundValue;
-
- g_ptr_array_add(relationshipsForOs, osLink);
- return 0;
-}
-
-static int __osinfoAddOsRelationshipByType(OsinfoOs *self,
- osinfoRelationship relshp,
- struct __osinfoOsLink *osLink)
-{
- gboolean found;
- gpointer origKey, foundValue;
- GPtrArray *relationshipsForType;
-
- found = g_tree_lookup_extended(self->priv->relationshipsByType, (gpointer) relshp, &origKey, &foundValue);
- if (!found) {
- relationshipsForType = g_ptr_array_new();
-
- g_tree_insert(self->priv->relationshipsByType, (gpointer) relshp, relationshipsForType);
- }
- else
- relationshipsForType = (GPtrArray *) foundValue;
-
- g_ptr_array_add(relationshipsForType, osLink);
- return 0;
-}
-
-static void __osinfoRemoveOsLink(OsinfoOs *self,
- gchar *otherOsId,
- osinfoRelationship relshp,
- struct __osinfoOsLink *osLink)
-{
- gboolean found;
- gpointer origKey, foundValue;
- GPtrArray *relationshipsForOs;
- GPtrArray *relationshipsForType;
-
- // First from by-os list
- found = g_tree_lookup_extended(self->priv->relationshipsByOs, otherOsId, &origKey, &foundValue);
- if (found) {
- relationshipsForOs = (GPtrArray *) foundValue;
- g_ptr_array_remove(relationshipsForOs, osLink);
- }
-
- // Now from by-relshp list
- found = g_tree_lookup_extended(self->priv->relationshipsByType, (gpointer) relshp, &origKey, &foundValue);
- if (found) {
- relationshipsForType = (GPtrArray *) foundValue;
- g_ptr_array_remove(relationshipsForType, osLink);
- }
-}
-
-int __osinfoAddOsRelationship (OsinfoOs *self, gchar *otherOsId, osinfoRelationship rel)
-{
- if ( !OSINFO_IS_OS(self) || !otherOsId)
- return -EINVAL;
-
- struct __osinfoOsLink *osLink = NULL;
- osLink = g_new0(struct __osinfoOsLink, 1);
-
- osLink->subjectOs = self;
- osLink->verb = rel;
-
- int ret;
- ret = __osinfoAddOsRelationshipByOs(self, otherOsId, rel, osLink);
- if (ret != 0)
- goto error_free;
-
- ret = __osinfoAddOsRelationshipByType(self, rel, osLink);
- if (ret != 0)
- goto error_cleanup;
-
- return ret;
-
-error_cleanup:
- __osinfoRemoveOsLink(self, otherOsId, rel, osLink);
-error_free:
- g_free(osLink);
- return ret;
-}
-
-
OsinfoDevice *osinfo_os_get_preferred_device(OsinfoOs *self, OsinfoHypervisor *hv, gchar *devType, OsinfoFilter *filter,
const gchar **driver)
{
@@ -211,16 +111,15 @@ OsinfoOsList *osinfo_os_get_related(OsinfoOs *self, osinfoRelationship relshp)
// Create our list
OsinfoOsList *newList = osinfo_oslist_new();
+ GList *tmp = self->priv->osLinks;
+
+ while (tmp) {
+ struct __osinfoOsLink *link = tmp->data;
+
+ if (link->relshp == relshp)
+ osinfo_list_add(OSINFO_LIST(newList), OSINFO_ENTITY(link->otherOs));
- GPtrArray *relatedOses = NULL;
- relatedOses = g_tree_lookup(self->priv->relationshipsByType, (gpointer) relshp);
- if (relatedOses) {
- int i, len;
- len = relatedOses->len;
- for (i = 0; i < len; i++) {
- struct __osinfoOsLink *osLink = g_ptr_array_index(relatedOses, i);
- osinfo_list_add(OSINFO_LIST (newList), OSINFO_ENTITY (osLink->directObjectOs));
- }
+ tmp = tmp->next;
}
return newList;
@@ -279,3 +178,17 @@ void osinfo_os_add_device(OsinfoOs *self, OsinfoHypervisor *hv, OsinfoDevice *de
}
}
+
+void osinfo_os_add_related_os(OsinfoOs *self, osinfoRelationship relshp, OsinfoOs *otheros)
+{
+ g_return_if_fail(OSINFO_IS_OS(self));
+ g_return_if_fail(OSINFO_IS_OS(otheros));
+
+ struct __osinfoOsLink *osLink = g_new0(struct __osinfoOsLink, 1);
+
+ g_object_ref(otheros);
+ osLink->otherOs = otheros;
+ osLink->relshp = relshp;
+
+ self->priv->osLinks = g_list_prepend(self->priv->osLinks, osLink);
+}
diff --git a/osinfo/osinfo_os.h b/osinfo/osinfo_os.h
index 033bdf4..7cc3e6c 100644
--- a/osinfo/osinfo_os.h
+++ b/osinfo/osinfo_os.h
@@ -60,4 +60,6 @@ OsinfoDeviceList *osinfo_os_get_devices(OsinfoOs *self, OsinfoHypervisor *hv, Os
void osinfo_os_add_device(OsinfoOs *self, OsinfoHypervisor *hv, OsinfoDevice *dev, const gchar *driver);
+void osinfo_os_add_related_os(OsinfoOs *self, osinfoRelationship relshp, OsinfoOs *otheros);
+
#endif /* __OSINFO_OS_H__ */
--
1.7.2.1
More information about the virt-tools-list
mailing list