You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@marmotta.apache.org by ss...@apache.org on 2015/12/15 21:33:23 UTC

marmotta git commit: fix iterator behaviour for a special case of queries

Repository: marmotta
Updated Branches:
  refs/heads/develop 79308ab5d -> dd1994a92


fix iterator behaviour for a special case of queries


Project: http://git-wip-us.apache.org/repos/asf/marmotta/repo
Commit: http://git-wip-us.apache.org/repos/asf/marmotta/commit/dd1994a9
Tree: http://git-wip-us.apache.org/repos/asf/marmotta/tree/dd1994a9
Diff: http://git-wip-us.apache.org/repos/asf/marmotta/diff/dd1994a9

Branch: refs/heads/develop
Commit: dd1994a92293338a7fb3674bbb7f1418b33c2bc6
Parents: 79308ab
Author: Sebastian Schaffert <ss...@apache.org>
Authored: Tue Dec 15 21:35:01 2015 +0100
Committer: Sebastian Schaffert <ss...@apache.org>
Committed: Tue Dec 15 21:35:01 2015 +0100

----------------------------------------------------------------------
 .../backend/persistence/leveldb_persistence.cc  | 46 ++++++-------
 libraries/ostrich/backend/util/iterator.h       | 72 ++++++++++++++++++++
 2 files changed, 91 insertions(+), 27 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/marmotta/blob/dd1994a9/libraries/ostrich/backend/persistence/leveldb_persistence.cc
----------------------------------------------------------------------
diff --git a/libraries/ostrich/backend/persistence/leveldb_persistence.cc b/libraries/ostrich/backend/persistence/leveldb_persistence.cc
index 9bb1ad2..5f18eff 100644
--- a/libraries/ostrich/backend/persistence/leveldb_persistence.cc
+++ b/libraries/ostrich/backend/persistence/leveldb_persistence.cc
@@ -251,27 +251,6 @@ class StatementRangeIterator : public LevelDBIterator<Statement> {
     char *hiKey;
 };
 
-
-/**
- * Check if a statement matches with a partial pattern.
- */
-bool matches(const Statement& stmt, const Statement& pattern) {
-    // equality operators defined in rdf_model.h
-    if (pattern.has_context() && stmt.context() != pattern.context()) {
-        return false;
-    }
-    if (pattern.has_subject() && stmt.subject() != pattern.subject()) {
-        return false;
-    }
-    if (pattern.has_predicate() && stmt.predicate() != pattern.predicate()) {
-        return false;
-    }
-    if (pattern.has_object() && stmt.object() != pattern.object()) {
-        return false;
-    }
-    return true;
-}
-
 }  // namespace
 
 
@@ -468,8 +447,23 @@ std::unique_ptr<LevelDBPersistence::StatementIterator> LevelDBPersistence::GetSt
             break;
     };
 
-    return std::unique_ptr<StatementIterator>(new StatementRangeIterator(
-            db->NewIterator(leveldb::ReadOptions()), query.MinKey(), query.MaxKey()));
+    return std::unique_ptr<StatementIterator>(
+            new util::FilteringIterator<Statement>(
+                    new StatementRangeIterator(
+                            db->NewIterator(leveldb::ReadOptions()), query.MinKey(), query.MaxKey()),
+                    [&pattern](const Statement& stmt) -> bool {
+                        // equality operators defined in rdf_model.h
+                        if (pattern.has_context() && stmt.context() != pattern.context()) {
+                            return false;
+                        }
+                        if (pattern.has_subject() && stmt.subject() != pattern.subject()) {
+                            return false;
+                        }
+                        if (pattern.has_predicate() && stmt.predicate() != pattern.predicate()) {
+                            return false;
+                        }
+                        return !(pattern.has_object() && stmt.object() != pattern.object());
+                    }));
 }
 
 
@@ -480,10 +474,8 @@ void LevelDBPersistence::GetStatements(
 
     bool cbsuccess = true;
     for(auto it = GetStatements(pattern); cbsuccess && it->hasNext(); ++(*it)) {
-        if (matches(**it, pattern)) {
-            cbsuccess = callback(**it);
-            count++;
-        }
+        cbsuccess = callback(**it);
+        count++;
     }
 
     DLOG(INFO) << "Get statements done (count=" << count << ", time="

http://git-wip-us.apache.org/repos/asf/marmotta/blob/dd1994a9/libraries/ostrich/backend/util/iterator.h
----------------------------------------------------------------------
diff --git a/libraries/ostrich/backend/util/iterator.h b/libraries/ostrich/backend/util/iterator.h
index cb95d8b..002c24f 100644
--- a/libraries/ostrich/backend/util/iterator.h
+++ b/libraries/ostrich/backend/util/iterator.h
@@ -124,6 +124,78 @@ class SingletonIterator : public CloseableIterator<T> {
 
 };
 
+
+template<typename T>
+class FilteringIterator : public CloseableIterator<T> {
+ public:
+    using PredicateFn = std::function<bool(const T&)>;
+
+    /**
+     * Create a filtering iterator using the given predicate as filter.
+     * The predicate function should return true for accepted values.
+     * Takes ownership of the iterator passed as argument.
+     */
+    FilteringIterator(CloseableIterator<T>* it,  PredicateFn pred)
+            : it(it), pred(pred), nextExists(false) {
+        // run findNext twice so both current and next are set
+        findNext();
+        findNext();
+    }
+
+    /**
+     * Increment iterator to next element.
+    */
+    CloseableIterator<T>& operator++() override {
+        findNext();
+        return *this;
+    };
+
+    /**
+     * Dereference iterator, returning a reference to the current element.
+     */
+    T& operator*() override {
+        return current;
+    };
+
+    /**
+     * Dereference iterator, returning a pointer to the current element.
+     */
+    T* operator->() override {
+        return &current;
+    };
+
+    /**
+     * Return true in case the iterator has more elements.
+     */
+    bool hasNext() override {
+        return nextExists;
+    };
+
+
+ private:
+    std::unique_ptr<CloseableIterator<T>> it;
+    PredicateFn pred;
+
+    T current;
+    T next;
+
+    bool nextExists;
+
+    void findNext() {
+        current = next;
+        nextExists = false;
+
+        while (it->hasNext()) {
+            if (pred(**it)) {
+                next = **it;
+                nextExists = true;
+                break;
+            }
+        }
+    }
+};
+
+
 }
 }