[Zope-Checkins] CVS: Zope/lib/python/Products/ZCatalog - Catalog.py:1.101

Casey Duncan casey@zope.com
Fri, 6 Dec 2002 16:53:20 -0500


Update of /cvs-repository/Zope/lib/python/Products/ZCatalog
In directory cvs.zope.org:/tmp/cvs-serv5939

Modified Files:
	Catalog.py 
Log Message:
Changes to non-merged results returned by search:

* For unsorted sets, merged and non-merged results are identical (lazy results)

* For sorted sets, merged results are lazy and non-merged are lists of three tuples that can later be merged and sorted using mergeResults

The mergeResults function has been simplified greatly and now simply accepts a list of result sets in its first argument.


=== Zope/lib/python/Products/ZCatalog/Catalog.py 1.100 => 1.101 ===
--- Zope/lib/python/Products/ZCatalog/Catalog.py:1.100	Thu Dec  5 16:17:04 2002
+++ Zope/lib/python/Products/ZCatalog/Catalog.py	Fri Dec  6 16:53:20 2002
@@ -33,7 +33,7 @@
 from bisect import bisect
 
 class Catalog(Persistent, Acquisition.Implicit, ExtensionClass.Base):
-    """ An Object Catalog
+    """ An Object Catalog 
 
     An Object Catalog maintains a table of object metadata, and a
     series of manageable indexes to quickly search for objects
@@ -437,7 +437,6 @@
         still slice or batch the results as usual."""
 
         rs = None # resultset
-        result_count = 0
 
         # Indexes fulfill a fairly large contract here. We hand each
         # index the request mapping we are given (which may be composed
@@ -472,26 +471,20 @@
             # We take this to mean that the query was empty (an empty filter)
             # and so we return everything in the catalog
             if sort_index is None:
-                if merge:
-                    return LazyMap(
-                        self.instantiate, self.data.items(), len(self))
-                else:
-                    return self.data.keys()
+                return LazyMap(self.instantiate, self.data.items(), len(self))
             else:
-                result_count = len(self)
-                rs = self.sortResults(
+                return self.sortResults(
                     self.data, sort_index, reverse,  limit, merge)
         elif rs:
-            result_count = len(rs)
-            
             # We got some results from the indexes.
             # Sort and convert to sequences.
             if sort_index is None and hasattr(rs, 'values'):
                 # having a 'values' means we have a data structure with
                 # scores.  Build a new result set, sort it by score, reverse
                 # it, compute the normalized score, and Lazify it.
-                if not merge:
-                    return rs
+                
+                # For now we cannot return raw scores for later merging :^(
+                
                 rs = rs.byValue(0) # sort it by score
                 max = float(rs[0][0])
 
@@ -517,20 +510,16 @@
                 # no scores
                 if hasattr(rs, 'keys'):
                     rs = rs.keys()
+                return LazyMap(self.__getitem__, rs, len(rs))
             else:
                 # sort.  If there are scores, then this block is not
                 # reached, therefore 'sort-on' does not happen in the
                 # context of a text index query.  This should probably
                 # sort by relevance first, then the 'sort-on' attribute.
-                rs = self.sortResults(
-                    rs, sort_index, reverse, limit, merge)
-        
-        if merge:
-            rs = LazyMap(self.__getitem__, rs, len(rs))
-            # Give the application an opportunity to see how many results
-            # there really were, regardless of the limit value
-            rs.actual_result_count = result_count
-        return rs 
+                return self.sortResults(rs, sort_index, reverse, limit, merge)
+        else:
+            # Empty result set
+            return LazyCat(rs)
 
     def sortResults(self, rs, sort_index, reverse=0, limit=None, merge=1):
         # Sort a result set using a sort index. Return a lazy
@@ -583,7 +572,7 @@
                 result.sort()
                 if reverse:
                     result.reverse()
-                return LazyCat(LazyValues(result), length)
+                result = LazyCat(LazyValues(result), length)
             else:
                 return result            
         else:
@@ -610,7 +599,7 @@
                     result.sort()
                     if reverse:
                         result.reverse()
-                    return LazyValues(result)
+                    result = LazyValues(result)
                 else:
                     return result
             else: 
@@ -638,9 +627,13 @@
                             n += 1
                 result.reverse()
                 if merge:
-                    return LazyValues(result) 
+                    result = LazyValues(result) 
                 else:
-                    return result     
+                    return result
+        
+        result = LazyMap(self.__getitem__, result, len(result))
+        result.actual_result_count = len(rs)
+        return result
 
     def _get_sort_attr(self, attr, kw):
         """Helper function to find sort-on or sort-order."""
@@ -737,35 +730,23 @@
             return 0
         else:
             return 1
-   
+        
 
-def mergeResults(catalogs_results, has_sort_keys, reverse):
+def mergeResults(results, has_sort_keys, reverse):
     """Sort/merge sub-results, generating a flat sequence.
     
-    catalog_results is a sequence of (catalog, r) tuples. This allows you to
-    merge and sort results efficiently from multiple catalogs.
-
-    The contents of r depend on whether has_sort_keys is set.
-    If not has_sort_keys, r contains sequences of records.
-    If has_sort_keys, r contains pairs of (sort_key, sequence)
-    and now we have to sort the results.
+    results is a list of result set sequences, all with or without sort keys
     """
-    result = []
     if not has_sort_keys:
-        for catalog, r in catalogs_results:
-            if not r:
-                continue
-            result.append(LazyMap(catalog.__getitem__, r))
-        return LazyCat(result)
+        return LazyCat(results)
     else:
         # Concatenate the catalog results into one list and sort it
-        # Each result item consists of a list of tuples with three values:
+        # Each result record consists of a list of tuples with three values:
         # (sortkey, docid, catalog__getitem__)
-        for catalog, r in catalogs_results:
-            result.extend(r)
-        result.sort()
+        all = []
+        for r in results:
+            all.extend(r)
+        all.sort()
         if reverse:
-            result.reverse()
-        return LazyMap(lambda rec: rec[2](rec[1]), result, len(result))
-
-        
+            all.reverse()
+        return LazyMap(lambda rec: rec[2](rec[1]), all, len(all))