[PATCH 16/24] Properties return generators instead of lists

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Remove flattern_nested_list() and gen_list_item()

The things that needed flatten_nested_list are more suited to using
generators directly, rather than indirectly via gen_list_item. There are
a few instances where the code really *does* want a list instead of an
iterator, so some callsite changes were also needed.

Signed-off-by: Andy Grover <agrover@xxxxxxxxxx>
---
 rtslib/root.py   |   52 +++++++++++++++++++++++++++++-----------------------
 rtslib/target.py |   47 ++++++++++++++++-------------------------------
 rtslib/tcm.py    |   12 +++---------
 rtslib/utils.py  |   27 ---------------------------
 4 files changed, 48 insertions(+), 90 deletions(-)

diff --git a/rtslib/root.py b/rtslib/root.py
index 9c43834..12410d2 100644
--- a/rtslib/root.py
+++ b/rtslib/root.py
@@ -25,7 +25,7 @@ from node import CFSNode
 from target import Target, FabricModule, TPG, MappedLUN, LUN, NetworkPortal, NodeACL
 from tcm import FileIOBackstore, BlockBackstore
 from tcm import PSCSIBackstore, RDMCPBackstore
-from utils import RTSLibError, RTSLibBrokenLink, flatten_nested_list, modprobe
+from utils import RTSLibError, RTSLibBrokenLink, modprobe
 
 backstores = dict(
     fileio=FileIOBackstore,
@@ -77,12 +77,11 @@ class RTSRoot(CFSNode):
         self._check_self()
         targets = set([])
         for fabric_module in self.fabric_modules:
-            targets.update(fabric_module.targets)
-        return targets
+            for target in fabric_module.targets:
+                yield target
 
     def _list_backstores(self):
         self._check_self()
-        backstores = set([])
         if os.path.isdir("%s/core" % self.path):
             backstore_dirs = glob.glob("%s/core/*_*" % self.path)
             for backstore_dir in [os.path.basename(path)
@@ -91,48 +90,55 @@ class RTSRoot(CFSNode):
                                   backstore_dir)
                 if regex:
                     if regex.group(1) == "fileio":
-                        backstores.add(
-                            FileIOBackstore(int(regex.group(3)), 'lookup'))
+                        yield FileIOBackstore(int(regex.group(3)), 'lookup')
                     elif regex.group(1) == "pscsi":
-                        backstores.add(
-                            PSCSIBackstore(int(regex.group(3)), 'lookup'))
+                        yield PSCSIBackstore(int(regex.group(3)), 'lookup')
                     elif regex.group(1) == "iblock":
-                        backstores.add(
-                            BlockBackstore(int(regex.group(3)), 'lookup'))
+                        yield BlockBackstore(int(regex.group(3)), 'lookup')
                     elif regex.group(1) == "rd_mcp":
-                        backstores.add(
-                            RDMCPBackstore(int(regex.group(3)), 'lookup'))
-        return backstores
+                        yield RDMCPBackstore(int(regex.group(3)), 'lookup')
+
     def _list_storage_objects(self):
         self._check_self()
-        return set(flatten_nested_list([backstore.storage_objects
-                                        for backstore in self.backstores]))
+        for bs in self.backstores:
+            for so in bs.storage_objects:
+                yield so
 
     def _list_tpgs(self):
         self._check_self()
-        return set(flatten_nested_list([t.tpgs for t in self.targets]))
+        for t in self.targets:
+            for tpg in t.tpgs:
+                yield tpg
 
     def _list_node_acls(self):
         self._check_self()
-        return set(flatten_nested_list([t.node_acls for t in self.tpgs]))
+        for t in self.tpgs:
+            for node_acl in t.node_acls:
+                yield node_acl
 
     def _list_network_portals(self):
         self._check_self()
-        return set(flatten_nested_list([t.network_portals for t in self.tpgs]))
+        for t in self.tpgs:
+            for p in t.network_portals:
+                yield p
 
     def _list_luns(self):
         self._check_self()
-        return set(flatten_nested_list([t.luns for t in self.tpgs]))
+        for t in self.tpgs:
+            for lun in t.luns:
+                yield lun
 
     def _list_fabric_modules(self):
         self._check_self()
         mod_names = [mod_name[:-5] for mod_name in os.listdir(self.spec_dir)
                      if mod_name.endswith('.spec')]
-        modules = [FabricModule(mod_name) for mod_name in mod_names]
-        return modules
+        for name in mod_names:
+            yield FabricModule(name)
 
     def _list_loaded_fabric_modules(self):
-        return [fm for fm in self._list_fabric_modules() if fm.exists]
+        for module in self._list_fabric_modules():
+            if module.exists:
+                yield module
 
     def __str__(self):
         return "rtsadmin"
@@ -180,7 +186,7 @@ class RTSRoot(CFSNode):
         if clear_existing:
             self.clear_existing(confirm=True)
 
-        if not clear_existing and (self.storage_objects or self.targets):
+        if not clear_existing and (list(self.storage_objects) or list(self.targets)):
             raise RTSLibError("backstores or targets present, not restoring." +
                               " Set clear_existing=True?")
 
diff --git a/rtslib/target.py b/rtslib/target.py
index 584809e..a4b7939 100644
--- a/rtslib/target.py
+++ b/rtslib/target.py
@@ -196,13 +196,10 @@ class FabricModule(CFSNode):
 
     def _list_targets(self):
         if self.exists:
-            return set(
-                [Target(self, wwn, 'lookup')
-                 for wwn in os.listdir(self.path)
-                 if os.path.isdir("%s/%s" % (self.path, wwn))
-                 if wwn not in self.target_names_excludes])
-        else:
-            return set([])
+            for wwn in os.listdir(self.path):
+                if os.path.isdir("%s/%s" % (self.path, wwn)) and \
+                        wwn not in self.target_names_excludes:
+                    yield Target(self, wwn, 'lookup')
 
     def _get_version(self):
         if self.exists:
@@ -844,12 +841,9 @@ class NodeACL(CFSNode):
 
     def _list_mapped_luns(self):
         self._check_self()
-        mapped_luns = []
-        mapped_lun_dirs = glob.glob("%s/lun_*" % self.path)
-        for mapped_lun_dir in mapped_lun_dirs:
+        for mapped_lun_dir in glob.glob("%s/lun_*" % self.path):
             mapped_lun = int(os.path.basename(mapped_lun_dir).split("_")[1])
-            mapped_luns.append(MappedLUN(self, mapped_lun))
-        return mapped_luns
+            yield MappedLUN(self, mapped_lun)
 
     # NodeACL public stuff
     def has_feature(self, feature):
@@ -1063,10 +1057,9 @@ class TPG(CFSNode):
     def _list_network_portals(self):
         self._check_self()
         if not self.has_feature('nps'):
-            return []
-        network_portals = []
-        network_portal_dirs = os.listdir("%s/np" % self.path)
-        for network_portal_dir in network_portal_dirs:
+            return
+
+        for network_portal_dir in os.listdir("%s/np" % self.path):
             if network_portal_dir.startswith('['):
                 # IPv6 portals are [IPv6]:PORT
                 (ip_address, port) = \
@@ -1077,9 +1070,7 @@ class TPG(CFSNode):
                 (ip_address, port) = \
                         os.path.basename(network_portal_dir).split(":")
             port = int(port)
-            network_portals.append(
-                NetworkPortal(self, ip_address, port, 'lookup'))
-        return network_portals
+            yield NetworkPortal(self, ip_address, port, 'lookup')
 
     def _get_enable(self):
         self._check_self()
@@ -1146,24 +1137,21 @@ class TPG(CFSNode):
     def _list_node_acls(self):
         self._check_self()
         if not self.has_feature('acls'):
-            return []
-        node_acls = []
+            return
+
         node_acl_dirs = [os.path.basename(path)
                          for path in os.listdir("%s/acls" % self.path)]
         for node_acl_dir in node_acl_dirs:
-            node_acls.append(NodeACL(self, node_acl_dir, 'lookup'))
-        return node_acls
+            yield NodeACL(self, node_acl_dir, 'lookup')
 
     def _list_luns(self):
         self._check_self()
-        luns = []
         lun_dirs = [os.path.basename(path)
                     for path in os.listdir("%s/lun" % self.path)]
         for lun_dir in lun_dirs:
             lun = lun_dir.split('_')[1]
             lun = int(lun)
-            luns.append(LUN(self, lun))
-        return luns
+            yield LUN(self, lun)
 
     def _control(self, command):
         self._check_self()
@@ -1314,13 +1302,10 @@ class Target(CFSNode):
 
     def _list_tpgs(self):
         self._check_self()
-        tpgs = []
-        tpg_dirs = glob.glob("%s/tpgt*" % self.path)
-        for tpg_dir in tpg_dirs:
+        for tpg_dir in glob.glob("%s/tpgt*" % self.path):
             tag = os.path.basename(tpg_dir).split('_')[1]
             tag = int(tag)
-            tpgs.append(TPG(self, tag, 'lookup'))
-        return tpgs
+            yield TPG(self, tag, 'lookup')
 
     # Target public stuff
 
diff --git a/rtslib/tcm.py b/rtslib/tcm.py
index 326b8ad..d4c08ed 100644
--- a/rtslib/tcm.py
+++ b/rtslib/tcm.py
@@ -56,16 +56,12 @@ class Backstore(CFSNode):
 
     def _list_storage_objects(self):
         self._check_self()
-        storage_objects = []
         storage_object_names = [os.path.basename(s)
                                 for s in os.listdir(self.path)
                                 if s not in set(["hba_info", "hba_mode"])]
 
         for storage_object_name in storage_object_names:
-            storage_objects.append(self._storage_object_class(
-                self, storage_object_name))
-
-        return storage_objects
+            yield self._storage_object_class(self, storage_object_name)
 
     def _create_in_cfs_ine(self, mode):
         try:
@@ -399,13 +395,11 @@ class StorageObject(CFSNode):
 
     def _list_attached_luns(self):
         '''
-        Just returns a set of all luns attached to a storage object.
+        Generates all luns attached to a storage object.
         '''
         self._check_self()
-        luns = set([])
         for lun in self._gen_attached_luns():
-            luns.add(lun)
-        return luns
+            yield lun
 
     # StorageObject public stuff
 
diff --git a/rtslib/utils.py b/rtslib/utils.py
index 1cad383..d1be95b 100644
--- a/rtslib/utils.py
+++ b/rtslib/utils.py
@@ -54,33 +54,6 @@ class RTSLibNotInCFS(RTSLibError):
     '''
     pass
 
-def flatten_nested_list(nested_list):
-    '''
-    Function to flatten a nested list.
-
-    >>> import rtslib.utils as utils
-    >>> utils.flatten_nested_list([[1,2,3,[4,5,6]],[7,8],[[[9,10]],[11,]]])
-    [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
-
-    @param nested_list: A nested list (list of lists of lists etc.)
-    @type nested_list: list
-    @return: A list with only non-list elements
-    '''
-    return list(gen_list_item(nested_list))
-
-def gen_list_item(nested_list):
-    '''
-    The generator for flatten_nested_list().
-    It returns one by one items that are not a list, and recurses when
-    he finds an item that is a list.
-    '''
-    for item in nested_list:
-        if type(item) is list:
-            for nested_item in gen_list_item(item):
-                yield nested_item
-        else:
-            yield item
-
 def fwrite(path, string):
     '''
     This function writes a string to a file, and takes care of
-- 
1.7.1

--
To unsubscribe from this list: send the line "unsubscribe target-devel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux SCSI]     [Kernel Newbies]     [Linux SCSI Target Infrastructure]     [Share Photos]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Linux IIO]     [Device Mapper]

  Powered by Linux