[rygel] core: MediaContainer.search()



commit f73ae34131d80e05d11b6da1b3d13b07cc21adfb
Author: Zeeshan Ali (Khattak) <zeeshanak gnome org>
Date:   Thu Nov 5 16:52:29 2009 +0200

    core: MediaContainer.search()
    
    MediaContainer now provides a simple (but not efficient) implementation
    of search. The inefficiency mainly comes from the fact that it has no
    means to define the offset for each subcontainer as it does not know in
    advance how many object under that container will match the search
    criteria.

 src/rygel/rygel-media-container.vala |   64 ++++++++++++++++++++++++++++++++++
 src/rygel/rygel-search.vala          |   16 ++++++--
 2 files changed, 76 insertions(+), 4 deletions(-)
---
diff --git a/src/rygel/rygel-media-container.vala b/src/rygel/rygel-media-container.vala
index 501ce92..713a31c 100644
--- a/src/rygel/rygel-media-container.vala
+++ b/src/rygel/rygel-media-container.vala
@@ -21,6 +21,7 @@
  */
 
 using GUPnP;
+using Gee;
 
 /**
  * Represents a container (folder) for media items and containers. Provides
@@ -88,6 +89,69 @@ public abstract class Rygel.MediaContainer : MediaObject {
                                                     throws Error;
 
     /**
+     * Recursively searches for all media objects the satisfy the given search
+     * expression in this container.
+     *
+     * @param expression the search expression
+     * @param offet zero-based index of the first object to return
+     * @param max_count maximum number of objects to return
+     * @param total_matches the actual number of objects that satisfy the given
+     *        search expression
+     * @param cancellable optional cancellable for this operation
+     *
+     * return A list of media objects.
+     */
+    public virtual async Gee.List<MediaObject>? search (
+                                        SearchExpression   expression,
+                                        uint               offset,
+                                        uint               max_count,
+                                        out uint           total_matches,
+                                        Cancellable?       cancellable)
+                                        throws Error {
+        var result = new ArrayList<MediaObject> ();
+
+        var children = yield this.get_children (0, uint.MAX, cancellable);
+        foreach (var child in children) {
+            if (expression.satisfied_by (child)) {
+                result.add (child);
+            }
+
+            if (!(child is MediaContainer)) {
+                continue;
+            }
+
+            // Now continue the search inside the child container
+            var container = child as MediaContainer;
+            uint tmp;
+
+            var child_result = yield container.search (expression,
+                                                       0,
+                                                       0,
+                                                       out tmp,
+                                                       cancellable);
+
+            result.add_all (child_result);
+        }
+
+        total_matches = result.size;
+
+        // See if we need to slice the results
+        if (total_matches > 0 && (offset != 0 || max_count != 0)) {
+            uint stop;
+
+            if (max_count != 0) {
+                stop = offset + max_count;
+            } else {
+                stop = total_matches - 1;
+            }
+
+            return result.slice ((int) offset, (int) stop);
+        } else {
+            return result;
+        }
+    }
+
+    /**
      * Method to be be called each time this container is updated (metadata
      * changes for this container, items under it gets removed/added or their
      * metadata changes etc).
diff --git a/src/rygel/rygel-search.vala b/src/rygel/rygel-search.vala
index a63cd10..a7b195a 100644
--- a/src/rygel/rygel-search.vala
+++ b/src/rygel/rygel-search.vala
@@ -118,12 +118,20 @@ internal class Rygel.Search: GLib.Object, Rygel.StateMachine {
         return media_object as MediaContainer;
     }
 
-    private async ArrayList<MediaObject> fetch_results (
-                                        MediaContainer container) throws Error {
+    private async Gee.List<MediaObject> fetch_results (
+                                        MediaContainer container)
+                                        throws Error {
         this.update_id = container.update_id;
 
-        var results = new ArrayList<MediaObject> ();
-        this.number_returned = this.total_matches = results.size;
+        var parser = new Rygel.SearchCriteriaParser (this.search_criteria);
+        yield parser.run ();
+
+        var results = yield container.search (parser.expression,
+                                              this.index,
+                                              this.requested_count,
+                                              out this.total_matches,
+                                              this.cancellable);
+        this.number_returned = results.size;
 
         return results;
     }



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