//////////////////////////////////////////////////////////////////////////////// /// @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 //////////////////////////////////////////////////////////////////////////////// #include #include "Aql/RangeInfo.h" using namespace triagens::basics; using namespace triagens::aql; //////////////////////////////////////////////////////////////////////////////// /// @brief 3-way comparison of the tightness of upper or lower RangeInfoBounds. /// Returns -1 if is tighter than , 1 if is tighter than /// , and 0 if the bounds are the same. The argument should be /// -1 if we are comparing lower bounds and 1 if we are comparing upper bounds. /// /// If or is a nullptr, this indicates no bound. /// /// If ~ is the comparison and (x,y), (z,t) are RangeInfoBounds (i.e. x,z are /// Json values, y,t are booleans) that we are comparing as lower bounds, then /// the following holds: /// /// -1 x>z or (x=z, y=false, z=true) /// (x,y) ~ (z,t) = 0 x=z, y=t /// 1 z>x or (x=z, y=true, t=false) /// /// as upper bounds: /// /// -1 x_bound.json(), right->_bound.json()); if (cmp == 0 && (left->_include != right->_include)) { return (left->_include?1:-1); } return cmp * lowhigh; }; // the following isn't used for anything . . . /* RangesInfo* RangesInfofromJson (Json base) { RangesInfo* out = new RangesInfo(); for(size_t i = 0; i < base.size(); i++){ //loop over the ranges . . . std::string var = JsonHelper::getStringValue(base.at(i).json(), "var"); std::string attr = JsonHelper::getStringValue(base.at(i).json(), "attr"); out->insert(new RangeInfo(base.at(i))); } return out; }; */ //////////////////////////////////////////////////////////////////////////////// /// @brief insert if there is no range corresponding to variable name , /// and attribute , and otherwise intersection with existing range //////////////////////////////////////////////////////////////////////////////// // remove var and name from here, they are inside newRange anyway ! TODO void RangesInfo::insert (RangeInfo* newRange) { auto oldMap = find(newRange->_var); if (oldMap == nullptr) { // TODO add exception . . . auto newMap = std::unordered_map(); newMap.insert(make_pair(newRange->_attr, newRange)); _ranges.insert(std::make_pair(newRange->_var, newMap)); return; } auto it = oldMap->find(newRange->_attr); if (it == oldMap->end()) { // TODO add exception . . . oldMap->insert(make_pair(newRange->_attr, newRange)); return; } auto oldRange = (*it).second; if (!oldRange->_valid) { // intersection of the empty set with any set is empty! return; } //this case is not covered by those below . . . if (oldRange->is1ValueRangeInfo() && newRange->is1ValueRangeInfo()) { if (!TRI_CheckSameValueJson(oldRange->_low->_bound.json(), newRange->_low->_bound.json())) { oldRange->_valid = false; return; } } if (CompareRangeInfoBound(newRange->_low, oldRange->_low, -1) == -1) { oldRange->_low = newRange->_low; } if (CompareRangeInfoBound(newRange->_high, oldRange->_high, 1) == -1) { oldRange->_high = newRange->_high; } // check the new range bounds are valid if (oldRange->_low != nullptr && oldRange->_high != nullptr) { int cmp = TRI_CompareValuesJson(oldRange->_low->_bound.json(), oldRange->_high->_bound.json()); if (cmp == 1 || (cmp == 0 && !(oldRange->_low->_include == true && oldRange->_high->_include == true ))) { // range invalid oldRange->_valid = false; } } }; //////////////////////////////////////////////////////////////////////////////// /// @brief insert if there is no range corresponding to variable name , /// and attribute , and otherwise intersection with existing range //////////////////////////////////////////////////////////////////////////////// void RangesInfo::insert (std::string var, std::string name, RangeInfoBound* low, RangeInfoBound* high) { insert(new RangeInfo(var, name, low, high)); };