More performance fixes

Sort introspected children nodes to improve the chance of finding
ObjectManagers sooner rather than later (systemd does a recursive
listing of child nodes).

Remove unnecessary dbus calls when processing interfaces for
associations.  The existing code assumes that only object interfaces
are available to it but the new discovery mechanism uses
GetManagedObjects which includes the object properties.

Signed-off-by: Brad Bishop <bradleyb@fuzziesquirrel.com>
diff --git a/phosphor-mapper b/phosphor-mapper
index a2d007c..d44e8f6 100644
--- a/phosphor-mapper
+++ b/phosphor-mapper
@@ -86,7 +86,7 @@
             if dbus.BUS_DAEMON_IFACE + '.ObjectManager' in ifaces:
                 objs = self.__get_managed_objects(service, path)
                 for k, v in objs.iteritems():
-                    self.results[k] = v.keys()
+                    self.results[k] = v
             else:
                 children = filter(
                     bool,
@@ -94,7 +94,7 @@
                 children = [
                     self.__to_path(
                         path_elements + self.__to_path_elements(x))
-                    for x in children]
+                    for x in sorted(children)]
                 for child in children:
                     if child not in self.results:
                         self.__find_interfaces(service, child)
@@ -288,10 +288,23 @@
             self.process_old_owner(owned_name, old)
 
     def update_interfaces(self, path, owner, old, new):
+        # __xx -> intf list
+        # xx -> intf dict
+        if isinstance(old, dict):
+            __old = old.keys()
+        else:
+            __old = old
+            old = {x: {} for x in old}
+        if isinstance(new, dict):
+            __new = new.keys()
+        else:
+            __new = new
+            new = {x: {} for x in new}
+
         cache_entry = self.cache.setdefault(path, {})
         created = [] if self.has_interfaces(cache_entry) else [path]
-        added = list(set(new).difference(old))
-        removed = list(set(old).difference(new))
+        added = list(set(__new).difference(__old))
+        removed = list(set(__old).difference(__new))
         self.interfaces_append(cache_entry, owner, added)
         self.interfaces_remove(cache_entry, owner, removed, path)
         destroyed = [] if self.has_interfaces(cache_entry) else [path]
@@ -300,7 +313,7 @@
         new_assoc = []
         old_assoc = []
         if self.is_association(added):
-            new_assoc = self.dbus_get_associations(path, owner)
+            new_assoc = self.dbus_get_associations(path, owner, new)
         if self.is_association(removed):
             old_assoc = self.index_get_associations(path, [owner])
         self.update_associations(
@@ -308,9 +321,7 @@
 
     def add_items(self, owner, bus_items):
         for path, items in bus_items.iteritems():
-            # convert dbus types to native.
-            interfaces = [str(i) for i in items]
-            self.update_interfaces(path, str(owner), old=[], new=interfaces)
+            self.update_interfaces(path, str(owner), old=[], new=items)
 
     def discover(self, owners=[]):
         def match(iface):
@@ -444,7 +455,12 @@
         if not owners:
             del index[path]
 
-    def dbus_get_associations(self, path, owner):
+    def dbus_get_associations(self, path, owner, obj):
+        iface = obmc.dbuslib.enums.OBMC_ASSOCIATIONS_IFACE
+        if 'associations' in obj[iface]:
+            return obj[iface]['associations']
+
+        # fallback to dbus
         obj = self.bus.get_object(owner, path, introspect=False)
         iface = dbus.Interface(obj, dbus.PROPERTIES_IFACE)
         return [(str(f), str(r), str(e)) for f, r, e in iface.Get(