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 <[email protected]> Authored: Tue Dec 15 21:35:01 2015 +0100 Committer: Sebastian Schaffert <[email protected]> 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 ¤t; + }; + + /** + * 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; + } + } + } +}; + + } }
