void operator()(VPackSlice const& v, std::vector<VPackSlice>& resEdges, std::vector<VPackSlice>& neighbors) { int res = TRI_ERROR_NO_ERROR; for (auto const& edgeCollection : _block->_collectionInfos) { VPackBuilder result; TRI_ASSERT(edgeCollection != nullptr); if (_isReverse) { res = edgeCollection->getReverseEdgesCoordinator(v, result); } else { res = edgeCollection->getEdgesCoordinator(v, result); } if (res != TRI_ERROR_NO_ERROR) { THROW_ARANGO_EXCEPTION(res); } VPackSlice edges = result.slice().get("edges"); for (auto const& edge : VPackArrayIterator(edges)) { VPackSlice from = arangodb::Transaction::extractFromFromDocument(edge); if (from == v) { VPackSlice to = arangodb::Transaction::extractToFromDocument(edge); if (to != v) { resEdges.emplace_back(edge); neighbors.emplace_back(to); } } else { resEdges.emplace_back(edge); neighbors.emplace_back(from); } } // Make sure the data Slices are pointing to is not running out of scope. // This is not thread-safe! _block->_coordinatorCache.emplace_back(result.steal()); } }
void operator()(VPackSlice const& source, std::vector<ArangoDBPathFinder::Step*>& result) { int res = TRI_ERROR_NO_ERROR; for (auto const& edgeCollection : _block->_collectionInfos) { TRI_ASSERT(edgeCollection != nullptr); VPackBuilder edgesBuilder; if (_reverse) { res = edgeCollection->getReverseEdgesCoordinator(source, edgesBuilder); } else { res = edgeCollection->getEdgesCoordinator(source, edgesBuilder); } if (res != TRI_ERROR_NO_ERROR) { THROW_ARANGO_EXCEPTION(res); } std::unordered_map<VPackSlice, size_t> candidates; auto inserter = [&](VPackSlice const& s, VPackSlice const& t, double currentWeight, VPackSlice const& edge) { auto cand = candidates.find(t); if (cand == candidates.end()) { // Add weight auto step = std::make_unique<ArangoDBPathFinder::Step>( t, s, currentWeight, std::move(edge)); result.emplace_back(step.release()); candidates.emplace(t, result.size() - 1); } else { // Compare weight auto old = result[cand->second]; auto oldWeight = old->weight(); if (currentWeight < oldWeight) { old->setWeight(currentWeight); old->_predecessor = s; old->_edge = edge; } } }; VPackSlice edges = edgesBuilder.slice().get("edges"); for (auto const& edge : VPackArrayIterator(edges)) { VPackSlice from = arangodb::Transaction::extractFromFromDocument(edge); VPackSlice to = arangodb::Transaction::extractToFromDocument(edge); double currentWeight = edgeCollection->weightEdge(edge); if (from == source) { inserter(from, to, currentWeight, edge); } else { inserter(to, from, currentWeight, edge); } } _block->_coordinatorCache.emplace_back(edgesBuilder.steal()); } }
void DocumentAccessor::setToNull () { // check if already null if (_current != nullptr && _current->_type == TRI_JSON_NULL) { // already null. done! return; } _json.reset(TRI_CreateNullJson(TRI_UNKNOWN_MEM_ZONE)); if (_json.get() == nullptr) { THROW_ARANGO_EXCEPTION(TRI_ERROR_OUT_OF_MEMORY); } _current = _json.get(); TRI_ASSERT(_current != nullptr); }
std::shared_ptr<VPackBuilder> VelocyPackHelper::velocyPackFromFile( std::string const& path) { size_t length; char* content = TRI_SlurpFile(TRI_UNKNOWN_MEM_ZONE, path.c_str(), &length); if (content != nullptr) { // The Parser might THROW std::shared_ptr<VPackBuilder> b; try { auto b = VPackParser::fromJson(reinterpret_cast<uint8_t const*>(content), length); TRI_Free(TRI_UNKNOWN_MEM_ZONE, content); return b; } catch (...) { TRI_Free(TRI_UNKNOWN_MEM_ZONE, content); throw; } } THROW_ARANGO_EXCEPTION(TRI_ERROR_OUT_OF_MEMORY); }
void DocumentAccessor::lookupDocumentAttribute (char const* name, size_t nameLength) { if (*name == '_' && name[1] != '\0') { if (name[1] == 'k' && nameLength == 4 && memcmp(name, TRI_VOC_ATTRIBUTE_KEY, nameLength) == 0) { // _key value is copied into JSON char const* key = TRI_EXTRACT_MARKER_KEY(_mptr); if (key == nullptr) { setToNull(); return; } _json.reset(TRI_CreateStringCopyJson(TRI_UNKNOWN_MEM_ZONE, key, strlen(key))); if (_json.get() == nullptr) { THROW_ARANGO_EXCEPTION(TRI_ERROR_OUT_OF_MEMORY); } _current = _json.get(); return; } if (name[1] == 'i' && nameLength == 3 && memcmp(name, TRI_VOC_ATTRIBUTE_ID, nameLength) == 0) { // _id char buffer[512]; // big enough for max key length + max collection name length size_t pos = _resolver->getCollectionName(&buffer[0], _document->_info._cid); buffer[pos++] = '/'; char const* key = TRI_EXTRACT_MARKER_KEY(_mptr); if (key == nullptr) { setToNull(); return; } size_t len = strlen(key); memcpy(&buffer[pos], key, len); buffer[pos + len] = '\0'; _json.reset(TRI_CreateStringCopyJson(TRI_UNKNOWN_MEM_ZONE, &buffer[0], pos + len)); if (_json.get() == nullptr) { THROW_ARANGO_EXCEPTION(TRI_ERROR_OUT_OF_MEMORY); } _current = _json.get(); return; } if (name[1] == 'r' && nameLength == 4 && memcmp(name, TRI_VOC_ATTRIBUTE_REV, nameLength) == 0) { // _rev char buffer[21]; TRI_voc_rid_t rid = TRI_EXTRACT_MARKER_RID(_mptr); size_t len = TRI_StringUInt64InPlace(rid, &buffer[0]); _json.reset(TRI_CreateStringCopyJson(TRI_UNKNOWN_MEM_ZONE, &buffer[0], len)); if (_json.get() == nullptr) { THROW_ARANGO_EXCEPTION(TRI_ERROR_OUT_OF_MEMORY); } _current = _json.get(); return; } if (TRI_IS_EDGE_MARKER(_mptr)) { if (name[1] == 'f' && nameLength == 5 && memcmp(name, TRI_VOC_ATTRIBUTE_FROM, nameLength) == 0) { // _from char buffer[512]; // big enough for max key length + max collection name length size_t pos = _resolver->getCollectionNameCluster(&buffer[0], TRI_EXTRACT_MARKER_FROM_CID(_mptr)); buffer[pos++] = '/'; char const* key = TRI_EXTRACT_MARKER_FROM_KEY(_mptr); if (key == nullptr) { setToNull(); return; } size_t len = strlen(key); memcpy(&buffer[pos], key, len); buffer[pos + len] = '\0'; _json.reset(TRI_CreateStringCopyJson(TRI_UNKNOWN_MEM_ZONE, &buffer[0], pos + len)); if (_json.get() == nullptr) { THROW_ARANGO_EXCEPTION(TRI_ERROR_OUT_OF_MEMORY); } _current = _json.get(); return; } if (name[1] == 't' && nameLength == 3 && memcmp(name, TRI_VOC_ATTRIBUTE_TO, nameLength) == 0) { // to char buffer[512]; // big enough for max key length + max collection name length size_t pos = _resolver->getCollectionNameCluster(&buffer[0], TRI_EXTRACT_MARKER_TO_CID(_mptr)); buffer[pos++] = '/'; char const* key = TRI_EXTRACT_MARKER_TO_KEY(_mptr); if (key == nullptr) { setToNull(); return; } size_t len = strlen(key); memcpy(&buffer[pos], key, len); buffer[pos + len] = '\0'; _json.reset(TRI_CreateStringCopyJson(TRI_UNKNOWN_MEM_ZONE, &buffer[0], pos + len)); if (_json.get() == nullptr) { THROW_ARANGO_EXCEPTION(TRI_ERROR_OUT_OF_MEMORY); } _current = _json.get(); return; } } // fall-through intentional } auto shaper = _document->getShaper(); TRI_shape_pid_t pid = shaper->lookupAttributePathByName(name); if (pid == 0) { // attribute does not exist setToNull(); return; } // attribute exists TRI_shaped_json_t document; TRI_EXTRACT_SHAPED_JSON_MARKER(document, _mptr->getDataPtr()); TRI_shaped_json_t json; TRI_shape_t const* shape; bool ok = shaper->extractShapedJson(&document, 0, pid, &json, &shape); if (ok && shape != nullptr) { _json.reset(TRI_JsonShapedJson(shaper, &json)); if (_json.get() == nullptr) { THROW_ARANGO_EXCEPTION(TRI_ERROR_OUT_OF_MEMORY); } _current = _json.get(); return; } // not found setToNull(); }