1
0
Fork 0
arangodb/arangod/Aql/RangeInfo.h

218 lines
6.8 KiB
C++

////////////////////////////////////////////////////////////////////////////////
/// @brief Infrastructure for RangeInfo
///
/// @file arangod/Aql/RangeInfo.h
///
/// DISCLAIMER
///
/// Copyright 2010-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 triAGENS GmbH, Cologne, Germany
///
/// @author not James
/// @author Copyright 2014, triagens GmbH, Cologne, Germany
////////////////////////////////////////////////////////////////////////////////
#ifndef ARANGODB_AQL_RANGE_INFO_H
#define ARANGODB_AQL_RANGE_INFO_H 1
#include <Basics/Common.h>
#include <Basics/JsonHelper.h>
#include "Aql/AstNode.h"
//#include <VocBase/voc-types.h>
//#include <VocBase/vocbase.h>
//#include "Aql/Expression.h"
//#include "Aql/Index.h"
//#include "Aql/ModificationOptions.h"
//#include "Aql/Variable.h"
//#include "Aql/Types.h"
//#include "Aql/WalkerWorker.h"
//#include "Aql/Query.h"
#include "lib/Basics/json-utilities.h"
using Json = triagens::basics::Json;
namespace triagens {
namespace aql {
// -----------------------------------------------------------------------------
// --SECTION-- class RangeInfoBound
// -----------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
/// @brief struct to keep an upper or lower bound named _bound and a bool
/// _include which indicates if the _bound is included or not.
////////////////////////////////////////////////////////////////////////////////
struct RangeInfoBound {
RangeInfoBound(AstNode const* bound, bool include) : _include(include) {
_bound = Json(TRI_UNKNOWN_MEM_ZONE, bound->toJson(TRI_UNKNOWN_MEM_ZONE, true));
}
~RangeInfoBound(){}
RangeInfoBound ( RangeInfoBound const& copy ) = delete;
RangeInfoBound& operator= ( RangeInfoBound const& copy ) = delete;
Json toJson () const {
Json item(basics::Json::Array);
item("bound", Json(TRI_UNKNOWN_MEM_ZONE,
TRI_CopyJson(TRI_UNKNOWN_MEM_ZONE, _bound.json())))
("include", Json(_include));
return item;
}
Json _bound;
bool _include;
};
////////////////////////////////////////////////////////////////////////////////
/// @brief struct to keep a pair of RangeInfoBounds _low and _high, and _valid
/// to indicate if the range is valid (i.e. not of the form x<2 and x>3).
////////////////////////////////////////////////////////////////////////////////
struct RangeInfo{
RangeInfo ( RangeInfoBound const* low,
RangeInfoBound const* high )
: _low(low), _high(high), _valid(true) {}
RangeInfo( const RangeInfo& copy ) = delete;
RangeInfo& operator= ( RangeInfo const& copy ) = delete;
~RangeInfo(){
if(_low != nullptr){
delete _low;
}
if(_high != nullptr){
delete _high;
}
}
//TODO improve
Json toJson () {
Json item(basics::Json::Array);
if(_low != nullptr && _high != nullptr){
item("low", _low->toJson())
("high", _high->toJson())
("valid", Json(_valid));
}
else if(_low != nullptr){
item("low", _low->toJson())
("valid", Json(_valid));
}
else if(_high != nullptr){
item("high", _high->toJson())
("valid", Json(_valid));
}
return item;
}
std::string toString() {
return this->toJson().toString();
}
// is the range a unique value (i.e. something like x<=1 and x>=1)
bool is1ValueRangeInfo () { //i.e. the range only covers single value
return _valid && _low != nullptr && _high != nullptr &&
TRI_CheckSameValueJson(_low->_bound.json(), _high->_bound.json())
&& _low->_include && _high->_include;
}
RangeInfoBound const* _low;
RangeInfoBound const* _high;
bool _valid;
};
////////////////////////////////////////////////////////////////////////////////
/// @brief class to keep RangeInfos associated to variable and attribute names.
////////////////////////////////////////////////////////////////////////////////
class RangesInfo{
public:
RangesInfo( const RangesInfo& copy ) = delete;
RangesInfo& operator= ( RangesInfo const& copy ) = delete;
RangesInfo () : _ranges(){}
~RangesInfo(){}
// find the range info for variable <var> and attributes <name>
RangeInfo* find (std::string var, std::string name) const {
auto it1 = _ranges.find(var);
if (it1 == _ranges.end()) {
return nullptr;
}
auto it2 = it1->second.find(name);
if (it2 == it1->second.end()) {
return nullptr;
}
return (*it2).second;
}
// find the all the range infos for variable <var>
std::unordered_map<std::string, RangeInfo*>* find (std::string var) {
auto it = _ranges.find(var);
if (it == _ranges.end()) {
return nullptr;
}
return &((*it).second);
}
// insert if it's not already there and otherwise intersection with
// existing range
void insert (std::string var, std::string name,
RangeInfoBound* low, RangeInfoBound* high);
// the number of range infos stored
size_t size () const {
return _ranges.size();
}
std::string toString() const {
return this->toJson().toString();
}
Json toJson () const {
Json list(Json::List);
for (auto x : _ranges) {
for (auto y: x.second){
Json item(Json::Array);
item("var", Json(x.first))
("attribute name", Json(y.first))
("range info", y.second->toJson());
list(item);
}
}
return list;
}
private:
std::unordered_map<std::string, std::unordered_map<std::string, RangeInfo*>> _ranges;
};
}
}
#endif