1
0
Fork 0
arangodb/arangod/IResearch/IResearchLink.h

268 lines
13 KiB
C++

//////////////////////////////////////////////////////////////////////////////
/// DISCLAIMER
///
/// Copyright 2017 EMC Corporation
///
/// Licensed 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.
///
/// Copyright holder is EMC Corporation
///
/// @author Andrey Abramov
/// @author Vasiliy Nabatchikov
////////////////////////////////////////////////////////////////////////////////
#ifndef ARANGOD_IRESEARCH__IRESEARCH_LINK_H
#define ARANGOD_IRESEARCH__IRESEARCH_LINK_H 1
#include "index/directory_reader.hpp"
#include "index/index_writer.hpp"
#include "store/directory.hpp"
#include "utils/utf8_path.hpp"
#include "IResearchLinkMeta.h"
#include "IResearchViewMeta.h"
#include "Indexes/Index.h"
#include "Transaction/Status.h"
namespace arangodb {
namespace iresearch {
class AsyncMeta; // forward declaration
class IResearchView; // forward declaration
template <typename T>
class TypedResourceMutex; // forward declaration
////////////////////////////////////////////////////////////////////////////////
/// @brief common base class for functionality required to link an ArangoDB
/// LogicalCollection with an IResearchView
////////////////////////////////////////////////////////////////////////////////
class IResearchLink {
public:
typedef std::shared_ptr<TypedResourceMutex<IResearchLink>> AsyncLinkPtr;
//////////////////////////////////////////////////////////////////////////////
/// @brief a snapshot representation of the data-store
/// locked to prevent data store deallocation
//////////////////////////////////////////////////////////////////////////////
class Snapshot {
public:
Snapshot() noexcept {} // non-default implementation required for MacOS
Snapshot(std::unique_lock<irs::async_utils::read_write_mutex::read_mutex>&& lock,
irs::directory_reader&& reader) noexcept
: _lock(std::move(lock)), _reader(std::move(reader)) {
TRI_ASSERT(_lock.owns_lock());
}
operator irs::directory_reader const&() const noexcept { return _reader; }
private:
std::unique_lock<irs::async_utils::read_write_mutex::read_mutex> _lock; // lock preventing data store dealocation
const irs::directory_reader _reader;
};
virtual ~IResearchLink();
////////////////////////////////////////////////////////////////////////////////
/// @brief does this IResearch Link reference the supplied view
////////////////////////////////////////////////////////////////////////////////
bool operator==(LogicalView const& view) const noexcept;
bool operator!=(LogicalView const& view) const noexcept {
return !(*this == view);
}
////////////////////////////////////////////////////////////////////////////////
/// @brief does this iResearch Link match the meta definition
////////////////////////////////////////////////////////////////////////////////
bool operator==(IResearchLinkMeta const& meta) const noexcept;
bool operator!=(IResearchLinkMeta const& meta) const noexcept {
return !(*this == meta);
}
void afterTruncate(); // arangodb::Index override
////////////////////////////////////////////////////////////////////////////////
/// @brief insert a set of ArangoDB documents into an iResearch View using
/// '_meta' params
////////////////////////////////////////////////////////////////////////////////
virtual void batchInsert(
arangodb::transaction::Methods& trx,
std::vector<std::pair<arangodb::LocalDocumentId, arangodb::velocypack::Slice>> const& batch,
std::shared_ptr<arangodb::basics::LocalTaskQueue> queue); // arangodb::Index override
bool canBeDropped() const; // arangodb::Index override
//////////////////////////////////////////////////////////////////////////////
/// @return the associated collection
//////////////////////////////////////////////////////////////////////////////
arangodb::LogicalCollection& collection() const noexcept; // arangodb::Index override
//////////////////////////////////////////////////////////////////////////////
/// @brief mark the current data store state as te latest valid state
//////////////////////////////////////////////////////////////////////////////
arangodb::Result commit();
//////////////////////////////////////////////////////////////////////////////
/// @brief invoke internal data store consolidation with the specified policy
/// @return success
//////////////////////////////////////////////////////////////////////////////
arangodb::Result consolidate(IResearchViewMeta::ConsolidationPolicy const& policy,
irs::merge_writer::flush_progress_t const& progress,
bool runCleanupAfterConsolidation);
////////////////////////////////////////////////////////////////////////////////
/// @brief called when the iResearch Link is dropped
////////////////////////////////////////////////////////////////////////////////
arangodb::Result drop(); // arangodb::Index override
bool hasBatchInsert() const; // arangodb::Index override
bool hasSelectivityEstimate() const; // arangodb::Index override
////////////////////////////////////////////////////////////////////////////////
/// @brief insert an ArangoDB document into an iResearch View using '_meta'
/// params
////////////////////////////////////////////////////////////////////////////////
arangodb::Result insert(arangodb::transaction::Methods& trx,
arangodb::LocalDocumentId const& documentId,
arangodb::velocypack::Slice const& doc,
arangodb::Index::OperationMode mode); // arangodb::Index override
bool isSorted() const; // arangodb::Index override
bool isHidden() const; // arangodb::Index override
////////////////////////////////////////////////////////////////////////////////
/// @brief the identifier for this link
////////////////////////////////////////////////////////////////////////////////
TRI_idx_iid_t id() const noexcept;
////////////////////////////////////////////////////////////////////////////////
/// @brief fill and return a jSON description of a IResearchLink object
/// elements are appended to an existing object
/// @return success or set TRI_set_errno(...) and return false
////////////////////////////////////////////////////////////////////////////////
bool json(arangodb::velocypack::Builder& builder) const;
////////////////////////////////////////////////////////////////////////////////
/// @brief called when the iResearch Link is loaded into memory
////////////////////////////////////////////////////////////////////////////////
void load(); // arangodb::Index override
////////////////////////////////////////////////////////////////////////////////
/// @brief index comparator, used by the coordinator to detect if the
/// specified
/// definition is the same as this link
////////////////////////////////////////////////////////////////////////////////
bool matchesDefinition(arangodb::velocypack::Slice const& slice) const; // arangodb::Index override
////////////////////////////////////////////////////////////////////////////////
/// @brief amount of memory in bytes occupied by this iResearch Link
////////////////////////////////////////////////////////////////////////////////
size_t memory() const; // arangodb::Index override
//////////////////////////////////////////////////////////////////////////////
/// @brief update runtine data processing properties (not persisted)
/// @return success
//////////////////////////////////////////////////////////////////////////////
arangodb::Result properties(irs::index_writer::segment_options const& properties);
////////////////////////////////////////////////////////////////////////////////
/// @brief remove an ArangoDB document from an iResearch View
////////////////////////////////////////////////////////////////////////////////
arangodb::Result remove(arangodb::transaction::Methods& trx,
arangodb::LocalDocumentId const& documentId,
arangodb::velocypack::Slice const& doc,
arangodb::Index::OperationMode mode); // arangodb::Index override
///////////////////////////////////////////////////////////////////////////////
/// @brief 'this' for the lifetime of the link data-store
/// for use with asynchronous calls, e.g. callbacks, view
///////////////////////////////////////////////////////////////////////////////
AsyncLinkPtr self() const { return _asyncSelf; }
//////////////////////////////////////////////////////////////////////////////
/// @return pointer to an index reader containing the data store current
/// record snapshot
/// (nullptr == no data store snapshot availabe, e.g. error)
//////////////////////////////////////////////////////////////////////////////
Snapshot snapshot() const;
////////////////////////////////////////////////////////////////////////////////
/// @brief iResearch Link index type enum value
////////////////////////////////////////////////////////////////////////////////
arangodb::Index::IndexType type() const; // arangodb::Index override
////////////////////////////////////////////////////////////////////////////////
/// @brief iResearch Link index type string value
////////////////////////////////////////////////////////////////////////////////
char const* typeName() const; // arangodb::Index override
////////////////////////////////////////////////////////////////////////////////
/// @brief called when the iResearch Link is unloaded from memory
////////////////////////////////////////////////////////////////////////////////
arangodb::Result unload(); // arangodb::Index override
protected:
////////////////////////////////////////////////////////////////////////////////
/// @brief construct an uninitialized IResearch link, must call init(...)
/// after
////////////////////////////////////////////////////////////////////////////////
IResearchLink(TRI_idx_iid_t iid, arangodb::LogicalCollection& collection);
////////////////////////////////////////////////////////////////////////////////
/// @brief initialize from the specified definition used in make(...)
/// @return success
////////////////////////////////////////////////////////////////////////////////
arangodb::Result init(arangodb::velocypack::Slice const& definition);
////////////////////////////////////////////////////////////////////////////////
/// @return the associated IResearch view or nullptr if not associated
////////////////////////////////////////////////////////////////////////////////
std::shared_ptr<IResearchView> view() const;
private:
//////////////////////////////////////////////////////////////////////////////
/// @brief the underlying iresearch data store
//////////////////////////////////////////////////////////////////////////////
struct DataStore {
irs::directory::ptr _directory;
irs::utf8_path _path;
irs::directory_reader _reader;
irs::index_writer::ptr _writer;
operator bool() const noexcept { return _directory && _writer; }
};
AsyncLinkPtr _asyncSelf; // 'this' for the lifetime of the view (for use with
// asynchronous calls)
arangodb::LogicalCollection& _collection; // the linked collection
DataStore _dataStore; // the iresearch data store, protected by _asyncSelf->mutex()
TRI_idx_iid_t const _id; // the index identifier
std::atomic<bool> _inRecovery; // the link is currently in the WAL recovery state
IResearchLinkMeta const _meta; // how this collection should be indexed
// (read-only, set via init())
std::mutex _readerMutex; // prevents query cache double invalidation
std::function<void(arangodb::transaction::Methods& trx,
arangodb::transaction::Status status)>
_trxCallback; // for insert(...)/remove(...)
std::string const _viewGuid; // the identifier of the desired view
// (read-only, set via init())
//////////////////////////////////////////////////////////////////////////////
/// @brief initialize the data store with a new or from an existing directory
//////////////////////////////////////////////////////////////////////////////
arangodb::Result initDataStore();
}; // IResearchLink
} // namespace iresearch
} // namespace arangodb
#endif