blob: 7a3da17236a48e914805e0880ec173dde67458b3 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef MARMOTTA_PERSISTENCE_H
#define MARMOTTA_PERSISTENCE_H
#include <memory>
#include <string>
#include <functional>
#include <leveldb/db.h>
#include <leveldb/cache.h>
#include <leveldb/comparator.h>
#include "model/rdf_model.h"
#include "service/sail.pb.h"
#include "util/iterator.h"
namespace marmotta {
namespace persistence {
/**
* A custom comparator treating the bytes in the key as unsigned char.
*/
class KeyComparator : public leveldb::Comparator {
public:
int Compare(const leveldb::Slice& a, const leveldb::Slice& b) const;
const char* Name() const { return "KeyComparator"; }
void FindShortestSeparator(std::string*, const leveldb::Slice&) const { }
void FindShortSuccessor(std::string*) const { }
};
// Statistical data about updates.
struct UpdateStatistics {
UpdateStatistics()
: added_stmts(0), removed_stmts(0), added_ns(0), removed_ns(0) {}
int64_t added_stmts, removed_stmts, added_ns, removed_ns;
};
/**
* Persistence implementation based on the LevelDB high performance database.
*/
class LevelDBPersistence {
public:
typedef util::CloseableIterator<rdf::proto::Statement> StatementIterator;
typedef util::CloseableIterator<rdf::proto::Namespace> NamespaceIterator;
typedef util::CloseableIterator<service::proto::UpdateRequest> UpdateIterator;
typedef std::function<bool(const rdf::proto::Statement&)> StatementHandler;
typedef std::function<bool(const rdf::proto::Namespace&)> NamespaceHandler;
/**
* Initialise a new LevelDB database using the given path and cache size (bytes).
*/
LevelDBPersistence(const std::string& path, int64_t cacheSize);
/**
* Add the namespaces in the iterator to the database.
*/
int64_t AddNamespaces(NamespaceIterator& it);
/**
* Add the statements in the iterator to the database.
*/
int64_t AddStatements(StatementIterator& it);
/**
* Get all statements matching the pattern (which may have some fields
* unset to indicate wildcards). Call the callback function for each
* result.
*/
void GetStatements(const rdf::proto::Statement& pattern,
StatementHandler callback);
/**
* Get all statements matching the pattern (which may have some fields
* unset to indicate wildcards). Call the callback function for each
* result.
*/
std::unique_ptr<StatementIterator>
GetStatements(const rdf::proto::Statement& pattern);
/**
* Get all namespaces matching the pattern (which may have some of all
* fields unset to indicate wildcards). Call the callback function for
* each result.
*/
void GetNamespaces(const rdf::proto::Namespace &pattern,
NamespaceHandler callback);
/**
* Get all namespaces matching the pattern (which may have some of all
* fields unset to indicate wildcards). Call the callback function for
* each result.
*/
std::unique_ptr<NamespaceIterator>
GetNamespaces(const rdf::proto::Namespace &pattern);
/**
* Remove all statements matching the pattern (which may have some fields
* unset to indicate wildcards).
*/
int64_t RemoveStatements(const rdf::proto::Statement& pattern);
/**
* Apply a batch of updates (mixed statement/namespace adds and removes).
* The updates are collected in LevelDB batches and written atomically to
* the database when iteration ends.
*/
UpdateStatistics Update(UpdateIterator& it);
/**
* Return the size of this database.
*/
int64_t Size();
private:
std::unique_ptr<KeyComparator> comparator;
std::unique_ptr<leveldb::Cache> cache;
std::unique_ptr<leveldb::Options> options;
// We currently support efficient lookups by subject, context and object.
std::unique_ptr<leveldb::DB>
// Statement databases, indexed for query performance
db_spoc, db_cspo, db_opsc, db_pcos,
// Namespace databases
db_ns_prefix, db_ns_url,
// Triple store metadata.
db_meta;
/**
* Add the namespace to the given database batch operations.
*/
void AddNamespace(const rdf::proto::Namespace& ns,
leveldb::WriteBatch& ns_prefix, leveldb::WriteBatch& ns_url);
/**
* Add the namespace to the given database batch operations.
*/
void RemoveNamespace(const rdf::proto::Namespace& ns,
leveldb::WriteBatch& ns_prefix, leveldb::WriteBatch& ns_url);
/**
* Add the statement to the given database batch operations.
*/
void AddStatement(const rdf::proto::Statement& stmt,
leveldb::WriteBatch& spoc, leveldb::WriteBatch& cspo,
leveldb::WriteBatch& opsc, leveldb::WriteBatch&pcos);
/**
* Remove all statements matching the pattern (which may have some fields
* unset to indicate wildcards) from the given database batch operations.
*/
int64_t RemoveStatements(const rdf::proto::Statement& pattern,
leveldb::WriteBatch& spoc, leveldb::WriteBatch& cspo,
leveldb::WriteBatch& opsc, leveldb::WriteBatch&pcos);
};
} // namespace persistence
} // namespace marmotta
#endif //MARMOTTA_PERSISTENCE_H