/*
* FILE:
* opencog/persist/monospace/MonoStorage.h
*
* FUNCTION:
* Simple RocksDB-backed persistent storage.
*
* HISTORY:
* Copyright (c) 2020 Linas Vepstas <linasvepstas@gmail.com>
*
* LICENSE:
* SPDX-License-Identifier: AGPL-3.0-or-later
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License v3 as
* published by the Free Software Foundation and including the exceptions
* at http://opencog.org/wiki/Licenses
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program; if not, write to:
* Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef _ATOMSPACE_MONO_STORAGE_H
#define _ATOMSPACE_MONO_STORAGE_H
#include <atomic>
#include <mutex>
#include "rocksdb/db.h"
#include <opencog/persist/api/StorageNode.h>
#include <opencog/persist/rocks-types/atom_types.h>
namespace opencog
{
/** \addtogroup grp_persist
* @{
*/
class MonoSatisfyingSet;
class MonoStorage : public StorageNode
{
friend class MonoImplicator;
friend class MonoSatisfyingSet;
friend class MonoJoinCallback;
private:
void init(const char *, bool read_only = false);
std::string _uri;
rocksdb::DB* _rfile;
// True if opened in read-only mode.
bool _read_only;
// unique ID's
std::atomic_uint64_t _next_aid;
uint64_t strtoaid(const std::string&) const;
std::string aidtostr(uint64_t) const;
void write_aid(void);
// Issue of sid needs to be atomic.
std::mutex _mtx_sid;
#ifdef NEED_LIST_LOCK
// Guarantee atomic update of atom plus it's incoming set.
std::recursive_mutex _mtx_list;
#endif
// Exception due to unknown atom type.
bool _unknown_type;
// Assorted helper functions
std::string findAtom(const Handle&);
std::string writeAtom(const Handle&);
void appendToSidList(const std::string&, const std::string&);
void remFromSidList(const std::string&, const std::string&);
void storeValue(const std::string& skid,
const ValuePtr& vp);
ValuePtr getValue(const std::string&);
Handle getAtom(const std::string&);
Handle findAlpha(const Handle&, const std::string&, std::string&);
void getKeys(AtomSpace*, const std::string&, const Handle&);
void loadAtoms(AtomSpace*, const std::string& pfx);
void loadInset(AtomSpace*, const std::string& ist);
void appendToInset(const std::string&, const std::string&);
void remFromInset(const std::string&, const std::string&);
void removeSatom(const std::string&, const std::string&, bool, bool);
void remIncoming(const std::string&, const std::string&,
const std::string&);
size_t count_records(const std::string&);
public:
MonoStorage(std::string uri);
MonoStorage(const MonoStorage&) = delete; // disable copying
MonoStorage& operator=(const MonoStorage&) = delete; // disable assignment
virtual ~MonoStorage();
void open(void);
void open_read_only(void);
void close(void);
bool connected(void); // connection to DB is alive
void create(void) {}
void destroy(void) { kill_data(); /* TODO also delete the db */ }
void erase(void) { kill_data(); }
void kill_data(void); // destroy DB contents
void print_range(const std::string&); // Debugging utility
// AtomStorage interface
void getAtom(const Handle&);
Handle getLink(Type, const HandleSeq&);
void fetchIncomingSet(AtomSpace*, const Handle&);
void fetchIncomingByType(AtomSpace*, const Handle&, Type t);
void storeAtom(const Handle&, bool synchronous = false);
void removeAtom(AtomSpace*, const Handle&, bool recursive);
void storeValue(const Handle& atom, const Handle& key);
void updateValue(const Handle&, const Handle&, const ValuePtr&);
void loadValue(const Handle& atom, const Handle& key);
void loadType(AtomSpace*, Type);
void loadAtomSpace(AtomSpace*); // Load entire contents
void storeAtomSpace(const AtomSpace*); // Store entire contents
void barrier();
std::string monitor();
// Debugging and performance monitoring
void print_stats(void);
void clear_stats(void); // reset stats counters.
void checkdb(void);
};
class MonoStorageNode : public MonoStorage
{
public:
MonoStorageNode(Type t, const std::string&& uri) :
MonoStorage(std::move(uri))
{}
MonoStorageNode(const std::string&& uri) :
MonoStorage(std::move(uri))
{}
void setAtomSpace(AtomSpace* as)
{
// This is called with a null pointer when this
// Atom is extracted from the AtomSpace.
if (nullptr == as) close();
Atom::setAtomSpace(as);
}
static Handle factory(const Handle&);
};
NODE_PTR_DECL(MonoStorageNode)
#define createMonoStorageNode CREATE_DECL(MonoStorageNode)
/** @}*/
} // namespace opencog
#endif // _ATOMSPACE_MONO_STORAGE_H