1
0
Fork 0
arangodb/arangod/RocksDBEngine/RocksDBKeyBounds.h

277 lines
11 KiB
C++

////////////////////////////////////////////////////////////////////////////////
/// DISCLAIMER
///
/// Copyright 2014-2017 ArangoDB GmbH, Cologne, Germany
/// Copyright 2004-2014 triAGENS GmbH, Cologne, Germany
///
/// 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 ArangoDB GmbH, Cologne, Germany
///
/// @author Jan Steemann
/// @author Daniel H. Larkin
////////////////////////////////////////////////////////////////////////////////
#ifndef ARANGO_ROCKSDB_ROCKSDB_KEY_BOUNDS_H
#define ARANGO_ROCKSDB_ROCKSDB_KEY_BOUNDS_H 1
#include "Basics/Common.h"
#include "Basics/StringRef.h"
#include "RocksDBEngine/RocksDBTypes.h"
#include "VocBase/vocbase.h"
#include <rocksdb/slice.h>
#include <velocypack/Slice.h>
#include <velocypack/velocypack-aliases.h>
#include <iosfwd>
namespace arangodb {
class RocksDBKeyBounds {
public:
//////////////////////////////////////////////////////////////////////////////
/// @brief empty bounds
//////////////////////////////////////////////////////////////////////////////
static RocksDBKeyBounds Empty();
//////////////////////////////////////////////////////////////////////////////
/// @brief Bounds for list of all databases
//////////////////////////////////////////////////////////////////////////////
static RocksDBKeyBounds Databases();
//////////////////////////////////////////////////////////////////////////////
/// @brief Bounds for all collections belonging to a specified database
//////////////////////////////////////////////////////////////////////////////
static RocksDBKeyBounds DatabaseCollections(TRI_voc_tick_t databaseId);
//////////////////////////////////////////////////////////////////////////////
/// @brief Bounds for all documents belonging to a specified collection
//////////////////////////////////////////////////////////////////////////////
static RocksDBKeyBounds CollectionDocuments(uint64_t collectionObjectId);
//////////////////////////////////////////////////////////////////////////////
/// @brief Bounds for all index-entries- belonging to a specified primary
/// index
//////////////////////////////////////////////////////////////////////////////
static RocksDBKeyBounds PrimaryIndex(uint64_t indexId);
//////////////////////////////////////////////////////////////////////////////
/// @brief Bounds for all index-entries belonging to a specified edge index
//////////////////////////////////////////////////////////////////////////////
static RocksDBKeyBounds EdgeIndex(uint64_t indexId);
//////////////////////////////////////////////////////////////////////////////
/// @brief Bounds for all index-entries belonging to a specified edge index
/// related to the specified vertex
//////////////////////////////////////////////////////////////////////////////
static RocksDBKeyBounds EdgeIndexVertex(uint64_t indexId,
arangodb::StringRef const& vertexId);
//////////////////////////////////////////////////////////////////////////////
/// @brief Bounds for all index-entries belonging to a specified non-unique
/// index
//////////////////////////////////////////////////////////////////////////////
static RocksDBKeyBounds IndexEntries(uint64_t indexId);
//////////////////////////////////////////////////////////////////////////////
/// @brief Bounds for all entries belonging to a specified unique index
//////////////////////////////////////////////////////////////////////////////
static RocksDBKeyBounds UniqueIndex(uint64_t indexId);
//////////////////////////////////////////////////////////////////////////////
/// @brief Bounds for all entries of a fulltext index
//////////////////////////////////////////////////////////////////////////////
static RocksDBKeyBounds FulltextIndex(uint64_t indexId);
//////////////////////////////////////////////////////////////////////////////
/// @brief Bounds for all entries belonging to a specified unique index
//////////////////////////////////////////////////////////////////////////////
static RocksDBKeyBounds GeoIndex(uint64_t indexId);
static RocksDBKeyBounds GeoIndex(uint64_t indexId, bool isSlot);
//////////////////////////////////////////////////////////////////////////////
/// @brief Bounds for all index-entries within a value range belonging to a
/// specified non-unique index
//////////////////////////////////////////////////////////////////////////////
static RocksDBKeyBounds IndexRange(uint64_t indexId, VPackSlice const& left,
VPackSlice const& right);
//////////////////////////////////////////////////////////////////////////////
/// @brief Bounds for all documents within a value range belonging to a
/// specified unique index
//////////////////////////////////////////////////////////////////////////////
static RocksDBKeyBounds UniqueIndexRange(uint64_t indexId,
VPackSlice const& left,
VPackSlice const& right);
//////////////////////////////////////////////////////////////////////////////
/// @brief Bounds for all views belonging to a specified database
//////////////////////////////////////////////////////////////////////////////
static RocksDBKeyBounds DatabaseViews(TRI_voc_tick_t databaseId);
//////////////////////////////////////////////////////////////////////////////
/// @brief Bounds for all counter values
//////////////////////////////////////////////////////////////////////////////
static RocksDBKeyBounds CounterValues();
//////////////////////////////////////////////////////////////////////////////
/// @brief Bounds for all index estimate values
//////////////////////////////////////////////////////////////////////////////
static RocksDBKeyBounds IndexEstimateValues();
//////////////////////////////////////////////////////////////////////////////
/// @brief Bounds for all entries of a fulltext index, matching prefixes
//////////////////////////////////////////////////////////////////////////////
static RocksDBKeyBounds FulltextIndexPrefix(uint64_t,
arangodb::StringRef const&);
//////////////////////////////////////////////////////////////////////////////
/// @brief Bounds for all entries of a fulltext index, matching the word
//////////////////////////////////////////////////////////////////////////////
static RocksDBKeyBounds FulltextIndexComplete(uint64_t,
arangodb::StringRef const&);
public:
RocksDBKeyBounds(RocksDBKeyBounds const& other);
RocksDBKeyBounds(RocksDBKeyBounds&& other);
RocksDBKeyBounds& operator=(RocksDBKeyBounds const& other);
RocksDBKeyBounds& operator=(RocksDBKeyBounds&& other);
RocksDBEntryType type() const { return _type; }
//////////////////////////////////////////////////////////////////////////////
/// @brief Returns the left bound slice.
///
/// Forward iterators may use it->Seek(bound.start()) and reverse iterators
/// may check that the current key is greater than this value.
//////////////////////////////////////////////////////////////////////////////
rocksdb::Slice start() const {
return _internals.start();
}
//////////////////////////////////////////////////////////////////////////////
/// @brief Returns the right bound slice.
///
/// Reverse iterators may use it->SeekForPrev(bound.end()) and forward
/// iterators may check that the current key is less than this value.
//////////////////////////////////////////////////////////////////////////////
rocksdb::Slice end() const {
return _internals.end();
}
//////////////////////////////////////////////////////////////////////////////
/// @brief Returns the object ID for these bounds
///
/// This method is only valid for certain types of bounds: Documents and
/// Index entries.
//////////////////////////////////////////////////////////////////////////////
uint64_t objectId() const;
private:
RocksDBKeyBounds();
explicit RocksDBKeyBounds(RocksDBEntryType type);
RocksDBKeyBounds(RocksDBEntryType type, uint64_t first);
RocksDBKeyBounds(RocksDBEntryType type, uint64_t first,
arangodb::StringRef const& second);
RocksDBKeyBounds(RocksDBEntryType type, uint64_t first,
VPackSlice const& second, VPackSlice const& third);
private:
// private class that will hold both bounds in a single buffer (with only one allocation)
class BoundsBuffer {
friend class RocksDBKeyBounds;
public:
BoundsBuffer() : _separatorPosition(0) {}
BoundsBuffer(BoundsBuffer const& other)
: _buffer(other._buffer), _separatorPosition(other._separatorPosition) {
}
BoundsBuffer(BoundsBuffer&& other)
: _buffer(std::move(other._buffer)), _separatorPosition(other._separatorPosition) {
other._separatorPosition = 0;
}
BoundsBuffer& operator=(BoundsBuffer const& other) {
if (this != &other) {
_buffer = other._buffer;
_separatorPosition = other._separatorPosition;
}
return *this;
}
BoundsBuffer& operator=(BoundsBuffer&& other) {
if (this != &other) {
_buffer = std::move(other._buffer);
_separatorPosition = other._separatorPosition;
other._separatorPosition = 0;
}
return *this;
}
// reserve space for bounds
void reserve(size_t length) {
TRI_ASSERT(_separatorPosition == 0);
TRI_ASSERT(_buffer.empty());
_buffer.reserve(length);
}
// mark the end of the start buffer
void separate() {
TRI_ASSERT(_separatorPosition == 0);
TRI_ASSERT(!_buffer.empty());
_separatorPosition = _buffer.size();
}
// append a character
void push_back(char c) {
_buffer.push_back(c);
}
// return the internal buffer for modification or reading
std::string& buffer() { return _buffer; }
std::string const& buffer() const { return _buffer; }
// return a slice to the start buffer
rocksdb::Slice start() const {
TRI_ASSERT(_separatorPosition != 0);
return rocksdb::Slice(_buffer.data(), _separatorPosition);
}
// return a slice to the end buffer
rocksdb::Slice end() const {
TRI_ASSERT(_separatorPosition != 0);
return rocksdb::Slice(_buffer.data() + _separatorPosition, _buffer.size() - _separatorPosition);
}
private:
std::string _buffer;
size_t _separatorPosition;
};
BoundsBuffer& internals() { return _internals; }
BoundsBuffer const& internals() const { return _internals; }
static const char _stringSeparator;
RocksDBEntryType _type;
BoundsBuffer _internals;
};
std::ostream& operator<<(std::ostream&, RocksDBKeyBounds const&);
} // namespace arangodb
#endif