1
0
Fork 0

changed some APIs of AssocMulti

This commit is contained in:
Jan Steemann 2015-11-25 15:40:01 +01:00
parent c019a6ecd5
commit db078f1554
11 changed files with 169 additions and 127 deletions

View File

@ -147,13 +147,13 @@ BOOST_AUTO_TEST_CASE (tst_insert_few) {
void* r = 0;
ELEMENT(e1, 1, 123);
BOOST_CHECK_EQUAL(r, a1.insert(&e1, true, false));
BOOST_CHECK_EQUAL(r, a1.insert(nullptr, &e1, true, false));
BOOST_CHECK_EQUAL((uint32_t) 1, a1.size());
BOOST_CHECK_EQUAL(&e1, a1.lookup(&e1));
BOOST_CHECK_EQUAL(&e1, a1.lookup(nullptr, &e1));
BOOST_CHECK_EQUAL(&e1, a1.remove(&e1));
BOOST_CHECK_EQUAL(&e1, a1.remove(nullptr, &e1));
BOOST_CHECK_EQUAL((uint32_t) 0, a1.size());
BOOST_CHECK_EQUAL(r, a1.lookup(&e1));
BOOST_CHECK_EQUAL(r, a1.lookup(nullptr, &e1));
DESTROY_MULTI
}
@ -178,18 +178,18 @@ BOOST_AUTO_TEST_CASE (tst_insert_delete_many) {
for (i = 0;i < NUMBER_OF_ELEMENTS;i++) {
p = new data_container_t(i % MODULUS, i);
v.push_back(p);
BOOST_CHECK_EQUAL(n, a1.insert(p, true, false));
BOOST_CHECK_EQUAL(n, a1.insert(nullptr, p, true, false));
}
one_more = new data_container_t(NUMBER_OF_ELEMENTS % MODULUS,
NUMBER_OF_ELEMENTS);
// Now check it is there (by element):
for (i = 0;i < NUMBER_OF_ELEMENTS;i++) {
p = static_cast<data_container_t*>(a1.lookup(v[i]));
p = static_cast<data_container_t*>(a1.lookup(nullptr, v[i]));
BOOST_CHECK_EQUAL(p, v[i]);
}
// This should not be there:
p = static_cast<data_container_t*>(a1.lookup(one_more));
p = static_cast<data_container_t*>(a1.lookup(nullptr, one_more));
BOOST_CHECK_EQUAL(n, p);
// Now check by key:
@ -199,12 +199,12 @@ BOOST_AUTO_TEST_CASE (tst_insert_delete_many) {
int* space = static_cast<int*>(TRI_Allocate(TRI_UNKNOWN_MEM_ZONE,
sizeof(int) * NUMBER_OF_ELEMENTS / MODULUS,
true));
res = a1.lookupByKey(&i);
res = a1.lookupByKey(nullptr, &i);
BOOST_CHECK_EQUAL((int) res->size(),
(int) (NUMBER_OF_ELEMENTS / MODULUS));
// Now check its contents:
for (j = 0; j < res->size(); j++) {
data_container_t* q = static_cast<data_container_t*> (res->at(j));
data_container_t* q = static_cast<data_container_t*>(res->at(j));
BOOST_CHECK_EQUAL((int) (q->value % MODULUS), (int) i);
BOOST_CHECK_EQUAL(space[(q->value - i) / MODULUS], 0);
space[(q->value - i) / MODULUS] = 1;
@ -215,15 +215,15 @@ BOOST_AUTO_TEST_CASE (tst_insert_delete_many) {
// Delete some data:
for (i = 0;i < v.size();i += 3) {
BOOST_CHECK_EQUAL(v[i], a1.remove(v[i]));
BOOST_CHECK_EQUAL(v[i], a1.remove(nullptr, v[i]));
}
for (i = 0;i < v.size();i += 3) {
BOOST_CHECK_EQUAL(n, a1.remove(v[i]));
BOOST_CHECK_EQUAL(n, a1.remove(nullptr, v[i]));
}
// Now check which are there (by element):
for (i = 0;i < NUMBER_OF_ELEMENTS;i++) {
p = static_cast<data_container_t*> (a1.lookup(v[i]));
p = static_cast<data_container_t*>(a1.lookup(nullptr, v[i]));
if (i % 3 == 0) {
BOOST_CHECK_EQUAL(p,n);
}
@ -232,20 +232,20 @@ BOOST_AUTO_TEST_CASE (tst_insert_delete_many) {
}
}
// This should not be there:
p = static_cast<data_container_t*> (a1.lookup(one_more));
p = static_cast<data_container_t*>(a1.lookup(nullptr, one_more));
BOOST_CHECK_EQUAL(n, p);
// Delete some more:
for (i = 1;i < v.size();i += 3) {
BOOST_CHECK_EQUAL(v[i], a1.remove(v[i]));
BOOST_CHECK_EQUAL(v[i], a1.remove(nullptr, v[i]));
}
for (i = 1;i < v.size();i += 3) {
BOOST_CHECK_EQUAL(n, a1.remove(v[i]));
BOOST_CHECK_EQUAL(n, a1.remove(nullptr, v[i]));
}
// Now check which are there (by element):
for (i = 0;i < NUMBER_OF_ELEMENTS;i++) {
p = static_cast<data_container_t*> (a1.lookup(v[i]));
p = static_cast<data_container_t*>(a1.lookup(nullptr, v[i]));
if (i % 3 == 2) {
BOOST_CHECK_EQUAL(p,v[i]);
}
@ -254,24 +254,24 @@ BOOST_AUTO_TEST_CASE (tst_insert_delete_many) {
}
}
// This should not be there:
p = static_cast<data_container_t*> (a1.lookup(one_more));
p = static_cast<data_container_t*>(a1.lookup(nullptr, one_more));
BOOST_CHECK_EQUAL(n, p);
// Delete the rest:
for (i = 2;i < v.size();i += 3) {
BOOST_CHECK_EQUAL(v[i], a1.remove(v[i]));
BOOST_CHECK_EQUAL(v[i], a1.remove(nullptr, v[i]));
}
for (i = 2;i < v.size();i += 3) {
BOOST_CHECK_EQUAL(n, a1.remove(v[i]));
BOOST_CHECK_EQUAL(n, a1.remove(nullptr, v[i]));
}
// Now check which are there (by element):
for (i = 0;i < NUMBER_OF_ELEMENTS;i++) {
p = static_cast<data_container_t*> (a1.lookup(v[i]));
p = static_cast<data_container_t*>(a1.lookup(nullptr, v[i]));
BOOST_CHECK_EQUAL(p,n);
}
// This should not be there:
p = static_cast<data_container_t*> (a1.lookup(one_more));
p = static_cast<data_container_t*>(a1.lookup(nullptr, one_more));
BOOST_CHECK_EQUAL(n, p);
// Pull down data again:
for (i = 0;i < NUMBER_OF_ELEMENTS;i++) {

View File

@ -147,13 +147,13 @@ BOOST_AUTO_TEST_CASE (tst_insert_few) {
void* r = 0;
ELEMENT(e1, 1, 123);
BOOST_CHECK_EQUAL(r, a1.insert(&e1, true, false));
BOOST_CHECK_EQUAL(r, a1.insert(nullptr, &e1, true, false));
BOOST_CHECK_EQUAL((uint32_t) 1, a1.size());
BOOST_CHECK_EQUAL(&e1, a1.lookup(&e1));
BOOST_CHECK_EQUAL(&e1, a1.lookup(nullptr, &e1));
BOOST_CHECK_EQUAL(&e1, a1.remove(&e1));
BOOST_CHECK_EQUAL(&e1, a1.remove(nullptr, &e1));
BOOST_CHECK_EQUAL((uint32_t) 0, a1.size());
BOOST_CHECK_EQUAL(r, a1.lookup(&e1));
BOOST_CHECK_EQUAL(r, a1.lookup(nullptr, &e1));
DESTROY_MULTI
}
@ -178,18 +178,18 @@ BOOST_AUTO_TEST_CASE (tst_insert_delete_many) {
for (i = 0;i < NUMBER_OF_ELEMENTS;i++) {
p = new data_container_t(i % MODULUS, i);
v.push_back(p);
BOOST_CHECK_EQUAL(n, a1.insert(p, true, false));
BOOST_CHECK_EQUAL(n, a1.insert(nullptr, p, true, false));
}
one_more = new data_container_t(NUMBER_OF_ELEMENTS % MODULUS,
NUMBER_OF_ELEMENTS);
// Now check it is there (by element):
for (i = 0;i < NUMBER_OF_ELEMENTS;i++) {
p = static_cast<data_container_t*>(a1.lookup(v[i]));
p = static_cast<data_container_t*>(a1.lookup(nullptr, v[i]));
BOOST_CHECK_EQUAL(p, v[i]);
}
// This should not be there:
p = static_cast<data_container_t*>(a1.lookup(one_more));
p = static_cast<data_container_t*>(a1.lookup(nullptr, one_more));
BOOST_CHECK_EQUAL(n, p);
// Now check by key:
@ -199,7 +199,7 @@ BOOST_AUTO_TEST_CASE (tst_insert_delete_many) {
int* space = static_cast<int*>(TRI_Allocate(TRI_UNKNOWN_MEM_ZONE,
sizeof(int) * NUMBER_OF_ELEMENTS / MODULUS,
true));
res = a1.lookupByKey(&i);
res = a1.lookupByKey(nullptr, &i);
BOOST_CHECK_EQUAL((int) res->size(),
(int) (NUMBER_OF_ELEMENTS / MODULUS));
// Now check its contents:
@ -215,15 +215,15 @@ BOOST_AUTO_TEST_CASE (tst_insert_delete_many) {
// Delete some data:
for (i = 0;i < v.size();i += 3) {
BOOST_CHECK_EQUAL(v[i], a1.remove(v[i]));
BOOST_CHECK_EQUAL(v[i], a1.remove(nullptr, v[i]));
}
for (i = 0;i < v.size();i += 3) {
BOOST_CHECK_EQUAL(n, a1.remove(v[i]));
BOOST_CHECK_EQUAL(n, a1.remove(nullptr, v[i]));
}
// Now check which are there (by element):
for (i = 0;i < NUMBER_OF_ELEMENTS;i++) {
p = static_cast<data_container_t*> (a1.lookup(v[i]));
p = static_cast<data_container_t*>(a1.lookup(nullptr, v[i]));
if (i % 3 == 0) {
BOOST_CHECK_EQUAL(p,n);
}
@ -232,20 +232,20 @@ BOOST_AUTO_TEST_CASE (tst_insert_delete_many) {
}
}
// This should not be there:
p = static_cast<data_container_t*> (a1.lookup(one_more));
p = static_cast<data_container_t*>(a1.lookup(nullptr, one_more));
BOOST_CHECK_EQUAL(n, p);
// Delete some more:
for (i = 1;i < v.size();i += 3) {
BOOST_CHECK_EQUAL(v[i], a1.remove(v[i]));
BOOST_CHECK_EQUAL(v[i], a1.remove(nullptr, v[i]));
}
for (i = 1;i < v.size();i += 3) {
BOOST_CHECK_EQUAL(n, a1.remove(v[i]));
BOOST_CHECK_EQUAL(n, a1.remove(nullptr, v[i]));
}
// Now check which are there (by element):
for (i = 0;i < NUMBER_OF_ELEMENTS;i++) {
p = static_cast<data_container_t*> (a1.lookup(v[i]));
p = static_cast<data_container_t*>(a1.lookup(nullptr, v[i]));
if (i % 3 == 2) {
BOOST_CHECK_EQUAL(p,v[i]);
}
@ -254,24 +254,24 @@ BOOST_AUTO_TEST_CASE (tst_insert_delete_many) {
}
}
// This should not be there:
p = static_cast<data_container_t*> (a1.lookup(one_more));
p = static_cast<data_container_t*>(a1.lookup(nullptr, one_more));
BOOST_CHECK_EQUAL(n, p);
// Delete the rest:
for (i = 2;i < v.size();i += 3) {
BOOST_CHECK_EQUAL(v[i], a1.remove(v[i]));
BOOST_CHECK_EQUAL(v[i], a1.remove(nullptr, v[i]));
}
for (i = 2;i < v.size();i += 3) {
BOOST_CHECK_EQUAL(n, a1.remove(v[i]));
BOOST_CHECK_EQUAL(n, a1.remove(nullptr, v[i]));
}
// Now check which are there (by element):
for (i = 0;i < NUMBER_OF_ELEMENTS;i++) {
p = static_cast<data_container_t*> (a1.lookup(v[i]));
p = static_cast<data_container_t*>(a1.lookup(nullptr, v[i]));
BOOST_CHECK_EQUAL(p,n);
}
// This should not be there:
p = static_cast<data_container_t*> (a1.lookup(one_more));
p = static_cast<data_container_t*>(a1.lookup(nullptr, one_more));
BOOST_CHECK_EQUAL(n, p);
// Pull down data again:
for (i = 0;i < NUMBER_OF_ELEMENTS;i++) {

View File

@ -2413,6 +2413,7 @@ AqlValue Functions::Neighbors (triagens::aql::Query* query,
auto wc = [](TRI_doc_mptr_copy_t&) -> double { return 1; };
std::unique_ptr<EdgeCollectionInfo> eci(new EdgeCollectionInfo(
trx,
eCid,
trx->documentCollection(eCid),
wc
@ -3249,6 +3250,7 @@ AqlValue Functions::Edges (triagens::aql::Query* query,
char* key = const_cast<char*>(parts[1].c_str());
std::vector<TRI_doc_mptr_copy_t> edges = TRI_LookupEdgesDocumentCollection(
trx,
collection->_collection->_collection,
direction,
startCid,

View File

@ -351,7 +351,7 @@ TRI_doc_mptr_t* EdgeIndexIterator::next () {
TRI_ASSERT(_position == 0);
_posInBuffer = 0;
_last = nullptr;
_buffer = _index->lookupByKey(&_keys[_position], _batchSize);
_buffer = _index->lookupByKey(_trx, &_keys[_position], _batchSize);
// fallthrough intentional
}
else if (_posInBuffer >= _buffer->size()) {
@ -361,10 +361,10 @@ TRI_doc_mptr_t* EdgeIndexIterator::next () {
_posInBuffer = 0;
if (_last != nullptr) {
_buffer = _index->lookupByKeyContinue(_last, _batchSize);
_buffer = _index->lookupByKeyContinue(_trx, _last, _batchSize);
}
else {
_buffer = _index->lookupByKey(&_keys[_position], _batchSize);
_buffer = _index->lookupByKey(_trx, &_keys[_position], _batchSize);
}
}
@ -506,37 +506,37 @@ triagens::basics::Json EdgeIndex::toJsonFigures (TRI_memory_zone_t* zone) const
return json;
}
int EdgeIndex::insert (triagens::arango::Transaction*,
int EdgeIndex::insert (triagens::arango::Transaction* trx,
TRI_doc_mptr_t const* doc,
bool isRollback) {
auto element = const_cast<TRI_doc_mptr_t*>(doc);
_edgesFrom->insert(element, true, isRollback);
_edgesFrom->insert(trx, element, true, isRollback);
try {
_edgesTo->insert(element, true, isRollback);
_edgesTo->insert(trx, element, true, isRollback);
}
catch (...) {
_edgesFrom->remove(element);
_edgesFrom->remove(trx, element);
throw;
}
return TRI_ERROR_NO_ERROR;
}
int EdgeIndex::remove (triagens::arango::Transaction*,
int EdgeIndex::remove (triagens::arango::Transaction* trx,
TRI_doc_mptr_t const* doc,
bool) {
_edgesFrom->remove(doc);
_edgesTo->remove(doc);
_edgesFrom->remove(trx, doc);
_edgesTo->remove(trx, doc);
return TRI_ERROR_NO_ERROR;
}
int EdgeIndex::batchInsert (triagens::arango::Transaction*,
int EdgeIndex::batchInsert (triagens::arango::Transaction* trx,
std::vector<TRI_doc_mptr_t const*> const* documents,
size_t numThreads) {
_edgesFrom->batchInsert(reinterpret_cast<std::vector<TRI_doc_mptr_t *> const*>(documents), numThreads);
_edgesTo->batchInsert(reinterpret_cast<std::vector<TRI_doc_mptr_t *> const*>(documents), numThreads);
_edgesFrom->batchInsert(trx, reinterpret_cast<std::vector<TRI_doc_mptr_t *> const*>(documents), numThreads);
_edgesTo->batchInsert(trx, reinterpret_cast<std::vector<TRI_doc_mptr_t *> const*>(documents), numThreads);
return TRI_ERROR_NO_ERROR;
}
@ -553,7 +553,7 @@ int EdgeIndex::sizeHint (triagens::arango::Transaction* trx,
// set an initial size for the index for some new nodes to be created
// without resizing
int err = _edgesFrom->resize(static_cast<uint32_t>(size + 2049));
int err = _edgesFrom->resize(trx, static_cast<uint32_t>(size + 2049));
if (err != TRI_ERROR_NO_ERROR) {
return err;
@ -565,7 +565,7 @@ int EdgeIndex::sizeHint (triagens::arango::Transaction* trx,
// set an initial size for the index for some new nodes to be created
// without resizing
return _edgesTo->resize(static_cast<uint32_t>(size + 2049));
return _edgesTo->resize(trx, static_cast<uint32_t>(size + 2049));
}
////////////////////////////////////////////////////////////////////////////////

View File

@ -469,7 +469,7 @@ int HashIndex::sizeHint (triagens::arango::Transaction* trx,
return _uniqueArray->_hashArray->resize(size);
}
else {
return _multiArray->_hashArray->resize(size);
return _multiArray->_hashArray->resize(trx, size);
}
}
@ -494,7 +494,7 @@ int HashIndex::lookup (triagens::arango::Transaction* trx,
std::vector<TRI_index_element_t*>* results = nullptr;
try {
results = _multiArray->_hashArray->lookupByKey(searchValue);
results = _multiArray->_hashArray->lookupByKey(trx, searchValue);
}
catch (...) {
return TRI_ERROR_OUT_OF_MEMORY;
@ -539,7 +539,7 @@ int HashIndex::lookup (triagens::arango::Transaction* trx,
if (next == nullptr) {
try {
results = _multiArray->_hashArray->lookupByKey(searchValue, batchSize);
results = _multiArray->_hashArray->lookupByKey(trx, searchValue, batchSize);
}
catch (...) {
return TRI_ERROR_OUT_OF_MEMORY;
@ -547,7 +547,7 @@ int HashIndex::lookup (triagens::arango::Transaction* trx,
}
else {
try {
results = _multiArray->_hashArray->lookupByKeyContinue(next, batchSize);
results = _multiArray->_hashArray->lookupByKeyContinue(trx, next, batchSize);
}
catch (...) {
return TRI_ERROR_OUT_OF_MEMORY;
@ -668,12 +668,12 @@ int HashIndex::insertMulti (triagens::arango::Transaction* trx,
return res;
}
auto work = [this] (TRI_index_element_t*& element, bool isRollback) {
auto work = [this, trx] (TRI_index_element_t*& element, bool isRollback) {
TRI_IF_FAILURE("InsertHashIndex") {
THROW_ARANGO_EXCEPTION(TRI_ERROR_DEBUG);
}
TRI_index_element_t* found = _multiArray->_hashArray->insert(element, false, true);
TRI_index_element_t* found = _multiArray->_hashArray->insert(trx, element, false, true);
if (found != nullptr) {
// already got the exact same index entry. now free our local element...
@ -735,7 +735,7 @@ int HashIndex::batchInsertMulti (triagens::arango::Transaction* trx,
return res;
}
}
return _multiArray->_hashArray->batchInsert(&elements, numThreads);
return _multiArray->_hashArray->batchInsert(trx, &elements, numThreads);
}
int HashIndex::removeUniqueElement (triagens::arango::Transaction* trx,
@ -788,7 +788,7 @@ int HashIndex::removeMultiElement (triagens::arango::Transaction* trx,
return TRI_ERROR_DEBUG;
}
TRI_index_element_t* old = _multiArray->_hashArray->remove(element);
TRI_index_element_t* old = _multiArray->_hashArray->remove(trx, element);
if (old == nullptr) {
// not found

View File

@ -36,6 +36,12 @@
#include "VocBase/edge-collection.h"
#include "VocBase/ExampleMatcher.h"
namespace triagens {
namespace arango {
class Transaction;
}
}
class VocShaper;
////////////////////////////////////////////////////////////////////////////////
@ -256,8 +262,15 @@ typedef std::function<double(TRI_doc_mptr_copy_t& edge)> WeightCalculatorFunctio
////////////////////////////////////////////////////////////////////////////////
class EdgeCollectionInfo {
private:
////////////////////////////////////////////////////////////////////////////////
/// @brief the underlying transaction
////////////////////////////////////////////////////////////////////////////////
triagens::arango::Transaction* _trx;
////////////////////////////////////////////////////////////////////////////////
/// @brief edge collection
////////////////////////////////////////////////////////////////////////////////
@ -278,10 +291,12 @@ class EdgeCollectionInfo {
public:
EdgeCollectionInfo (TRI_voc_cid_t& edgeCollectionCid,
EdgeCollectionInfo (triagens::arango::Transaction* trx,
TRI_voc_cid_t& edgeCollectionCid,
TRI_document_collection_t* edgeCollection,
WeightCalculatorFunction weighter)
: _edgeCollectionCid(edgeCollectionCid),
: _trx(trx),
_edgeCollectionCid(edgeCollectionCid),
_edgeCollection(edgeCollection),
_weighter(weighter) {
}
@ -292,7 +307,7 @@ class EdgeCollectionInfo {
std::vector<TRI_doc_mptr_copy_t> getEdges (TRI_edge_direction_e direction,
VertexId const& vertexId) const {
return TRI_LookupEdgesDocumentCollection(_edgeCollection,
return TRI_LookupEdgesDocumentCollection(_trx, _edgeCollection,
direction, vertexId.cid, const_cast<char*>(vertexId.key));
}
@ -360,7 +375,6 @@ std::unique_ptr<ArangoDBPathFinder::Path> TRI_RunShortestPathSearch (
triagens::basics::traverser::ShortestPathOptions& opts
);
std::unique_ptr<ArangoDBConstDistancePathFinder::Path> TRI_RunSimpleShortestPathSearch (
std::vector<EdgeCollectionInfo*>& collectionInfos,
triagens::basics::traverser::ShortestPathOptions& opts

View File

@ -820,7 +820,7 @@ static void EdgesQuery (TRI_edge_direction_e direction,
continue;
}
std::vector<TRI_doc_mptr_copy_t>&& edges = TRI_LookupEdgesDocumentCollection(document, direction, cid, key.get());
std::vector<TRI_doc_mptr_copy_t>&& edges = TRI_LookupEdgesDocumentCollection(&trx, document, direction, cid, key.get());
for (size_t j = 0; j < edges.size(); ++j) {
v8::Handle<v8::Value> doc = WRAP_SHAPED_JSON(trx, col->_cid, edges[j].getDataPtr());
@ -855,7 +855,7 @@ static void EdgesQuery (TRI_edge_direction_e direction,
TRI_V8_THROW_EXCEPTION(res);
}
std::vector<TRI_doc_mptr_copy_t>&& edges = TRI_LookupEdgesDocumentCollection(document, direction, cid, key.get());
std::vector<TRI_doc_mptr_copy_t>&& edges = TRI_LookupEdgesDocumentCollection(&trx, document, direction, cid, key.get());
trx.finish(res);

View File

@ -2318,6 +2318,7 @@ static void JS_QueryShortestPath (const v8::FunctionCallbackInfo<v8::Value>& arg
auto cid = resolver->getCollectionId(it);
auto colObj = ditches.find(cid)->second.col->_collection->_collection;
edgeCollectionInfos.emplace_back(new EdgeCollectionInfo(
trx.get(),
cid,
colObj,
AttributeWeightCalculator(
@ -2331,6 +2332,7 @@ static void JS_QueryShortestPath (const v8::FunctionCallbackInfo<v8::Value>& arg
auto cid = resolver->getCollectionId(it);
auto colObj = ditches.find(cid)->second.col->_collection->_collection;
edgeCollectionInfos.emplace_back(new EdgeCollectionInfo(
trx.get(),
cid,
colObj,
HopWeightCalculator()
@ -2655,6 +2657,7 @@ static void JS_QueryNeighbors (const v8::FunctionCallbackInfo<v8::Value>& args)
auto cid = resolver->getCollectionId(it);
auto colObj = ditches.find(cid)->second.col->_collection->_collection;
edgeCollectionInfos.emplace_back(new EdgeCollectionInfo(
trx.get(),
cid,
colObj,
HopWeightCalculator()

View File

@ -80,7 +80,8 @@ static bool IsReflexive (TRI_doc_mptr_t const* mptr) {
/// opposite direction (with matchType 2 or 3) to find all counterparts
////////////////////////////////////////////////////////////////////////////////
static bool FindEdges (TRI_edge_direction_e direction,
static bool FindEdges (triagens::arango::Transaction* trx,
TRI_edge_direction_e direction,
triagens::arango::EdgeIndex* edgeIndex,
std::vector<TRI_doc_mptr_copy_t>& result,
TRI_edge_header_t const* entry,
@ -88,10 +89,10 @@ static bool FindEdges (TRI_edge_direction_e direction,
std::unique_ptr<std::vector<TRI_doc_mptr_t*>> found;
if (direction == TRI_EDGE_OUT) {
found.reset(edgeIndex->from()->lookupByKey(entry));
found.reset(edgeIndex->from()->lookupByKey(trx, entry));
}
else if (direction == TRI_EDGE_IN) {
found.reset(edgeIndex->to()->lookupByKey(entry));
found.reset(edgeIndex->to()->lookupByKey(trx, entry));
}
else {
TRI_ASSERT(false); // TRI_EDGE_ANY not supported here
@ -145,6 +146,7 @@ static bool FindEdges (TRI_edge_direction_e direction,
////////////////////////////////////////////////////////////////////////////////
std::vector<TRI_doc_mptr_copy_t> TRI_LookupEdgesDocumentCollection (
triagens::arango::Transaction* trx,
TRI_document_collection_t* document,
TRI_edge_direction_e direction,
TRI_voc_cid_t cid,
@ -164,17 +166,17 @@ std::vector<TRI_doc_mptr_copy_t> TRI_LookupEdgesDocumentCollection (
if (direction == TRI_EDGE_IN) {
// get all edges with a matching IN vertex
FindEdges(TRI_EDGE_IN, edgeIndex, result, &entry, 1);
FindEdges(trx, TRI_EDGE_IN, edgeIndex, result, &entry, 1);
}
else if (direction == TRI_EDGE_OUT) {
// get all edges with a matching OUT vertex
FindEdges(TRI_EDGE_OUT, edgeIndex, result, &entry, 1);
FindEdges(trx, TRI_EDGE_OUT, edgeIndex, result, &entry, 1);
}
else if (direction == TRI_EDGE_ANY) {
// get all edges with a matching IN vertex
FindEdges(TRI_EDGE_IN, edgeIndex, result, &entry, 1);
FindEdges(trx, TRI_EDGE_IN, edgeIndex, result, &entry, 1);
// add all non-reflexive edges with a matching OUT vertex
FindEdges(TRI_EDGE_OUT, edgeIndex, result, &entry, 3);
FindEdges(trx, TRI_EDGE_OUT, edgeIndex, result, &entry, 3);
}
return result;

View File

@ -112,6 +112,7 @@ struct TRI_edge_index_iterator_t {
////////////////////////////////////////////////////////////////////////////////
std::vector<TRI_doc_mptr_copy_t> TRI_LookupEdgesDocumentCollection (
triagens::arango::Transaction*,
struct TRI_document_collection_t*,
TRI_edge_direction_e,
TRI_voc_cid_t,

View File

@ -137,6 +137,9 @@ namespace triagens {
template <class Key, class Element, class IndexType = size_t,
bool useHashCache = true>
class AssocMulti {
private:
typedef void UserData;
public:
static IndexType const INVALID_INDEX = ((IndexType)0)-1;
@ -186,7 +189,6 @@ namespace triagens {
uint64_t _nrProbesD; // statistics: number of misses while removing
#endif
HashKeyFuncType const _hashKey;
HashElementFuncType const _hashElement;
IsEqualKeyElementFuncType const _isEqualKeyElement;
@ -285,7 +287,6 @@ namespace triagens {
}
}
// -----------------------------------------------------------------------------
// --SECTION-- public methods
// -----------------------------------------------------------------------------
@ -359,7 +360,8 @@ namespace triagens {
/// @brief adds a key/element to the array
////////////////////////////////////////////////////////////////////////////////
Element* insert (Element* element,
Element* insert (UserData* userData,
Element* element,
bool overwrite,
bool checkEquality) {
@ -369,17 +371,17 @@ namespace triagens {
// for sure no duplicate elements will be inserted
#ifdef TRI_CHECK_MULTI_POINTER_HASH
check(true, true);
check(userData, true, true);
#endif
// compute the hash by the key only first
uint64_t hashByKey = _hashElement(element, true);
Bucket& b = _buckets[hashByKey & _bucketsMask];
auto result = doInsert(element, hashByKey, b, overwrite, checkEquality);
auto result = doInsert(userData, element, hashByKey, b, overwrite, checkEquality);
#ifdef TRI_CHECK_MULTI_POINTER_HASH
check(true, true);
check(userData, true, true);
#endif
return result;
@ -389,10 +391,11 @@ namespace triagens {
/// @brief adds multiple elements to the array
////////////////////////////////////////////////////////////////////////////////
int batchInsert (std::vector<Element*> const* data,
int batchInsert (UserData* userData,
std::vector<Element*> const* data,
size_t numThreads) {
#ifdef TRI_CHECK_MULTI_POINTER_HASH
check(true, true);
check(userData, true, true);
#endif
std::atomic<int> res(TRI_ERROR_NO_ERROR);
@ -430,7 +433,7 @@ namespace triagens {
it = partitions.emplace(bucketId, DocumentsPerBucket()).first;
}
(*it).second.emplace_back(std::make_pair(elements[i], hashByKey));
(*it).second.emplace_back(elements[i], hashByKey);
}
// transfer ownership to the central map
@ -503,7 +506,7 @@ namespace triagens {
for (auto const& it2 : it.second) {
for (auto const& it3 : it2) {
doInsert(it3.first, it3.second, b, true, false);
doInsert(userData, it3.first, it3.second, b, true, false);
}
}
}
@ -532,7 +535,7 @@ namespace triagens {
}
#ifdef TRI_CHECK_MULTI_POINTER_HASH
check(true, true);
check(userData, true, true);
#endif
return res.load();
}
@ -559,7 +562,8 @@ namespace triagens {
/// @brief adds a key/element to the array
////////////////////////////////////////////////////////////////////////////////
Element* doInsert (Element* element,
Element* doInsert (UserData* userData,
Element* element,
uint64_t hashByKey,
Bucket& b,
bool const overwrite,
@ -572,7 +576,7 @@ namespace triagens {
// if we were adding and the table is more than 2/3 full, extend it
if (2 * b._nrAlloc < 3 * b._nrUsed) {
resizeInternal(b, 2 * b._nrAlloc + 1);
resizeInternal(userData, b, 2 * b._nrAlloc + 1);
}
#ifdef TRI_INTERNAL_STATS
@ -642,7 +646,7 @@ namespace triagens {
// Now find a new home for element in this linked list:
uint64_t hashByElm;
IndexType j = findElementPlace(b, element, checkEquality, hashByElm);
IndexType j = findElementPlace(userData, b, element, checkEquality, hashByElm);
old = b._table[j].ptr;
@ -681,10 +685,13 @@ namespace triagens {
/// is already known. This is for example the case when resizing.
////////////////////////////////////////////////////////////////////////////////
IndexType insertFirst (Bucket& b, Element* element, uint64_t hashByKey) {
IndexType insertFirst (UserData* userData,
Bucket& b,
Element* element,
uint64_t hashByKey) {
#ifdef TRI_CHECK_MULTI_POINTER_HASH
check(true, true);
check(userData, true, true);
#endif
#ifdef TRI_INTERNAL_STATS
@ -706,7 +713,7 @@ namespace triagens {
b._nrUsed++;
// no collision generated here!
#ifdef TRI_CHECK_MULTI_POINTER_HASH
check(true, true);
check(userData, true, true);
#endif
return i;
}
@ -731,7 +738,7 @@ namespace triagens {
b._nrUsed++;
// no collision generated here either!
#ifdef TRI_CHECK_MULTI_POINTER_HASH
check(true, true);
check(userData, true, true);
#endif
return i;
}
@ -743,11 +750,14 @@ namespace triagens {
/// example the case when resizing.
////////////////////////////////////////////////////////////////////////////////
void insertFurther (Bucket& b, Element* element,
uint64_t hashByKey, uint64_t hashByElm,
void insertFurther (UserData* userData,
Bucket& b,
Element* element,
uint64_t hashByKey,
uint64_t hashByElm,
IndexType firstPosition) {
#ifdef TRI_CHECK_MULTI_POINTER_HASH
check(true, true);
check(userData, true, true);
#endif
#ifdef TRI_INTERNAL_STATS
@ -784,7 +794,7 @@ namespace triagens {
b._nrCollisions++;
#ifdef TRI_CHECK_MULTI_POINTER_HASH
check(true, true);
check(userData, true, true);
#endif
}
@ -794,7 +804,8 @@ namespace triagens {
public:
Element* lookup (Element const* element) const {
Element* lookup (UserData* userData,
Element const* element) const {
IndexType i;
#ifdef TRI_INTERNAL_STATS
@ -803,7 +814,7 @@ namespace triagens {
#endif
Bucket* b;
i = lookupByElement(element, b);
i = lookupByElement(userData, element, b);
return b->_table[i].ptr;
}
@ -811,7 +822,8 @@ namespace triagens {
/// @brief lookups an element given a key
////////////////////////////////////////////////////////////////////////////////
std::vector<Element*>* lookupByKey (Key const* key,
std::vector<Element*>* lookupByKey (UserData* userData,
Key const* key,
size_t limit = 0) const {
std::unique_ptr<std::vector<Element*>> result
(new std::vector<Element*>());
@ -859,6 +871,7 @@ namespace triagens {
////////////////////////////////////////////////////////////////////////////////
std::vector<Element*>* lookupWithElementByKey (
UserData* userData,
Element const* element,
size_t limit = 0) const {
std::unique_ptr<std::vector<Element*>> result
@ -908,6 +921,7 @@ namespace triagens {
////////////////////////////////////////////////////////////////////////////////
std::vector<Element*>* lookupWithElementByKeyContinue (
UserData* userData,
Element const* element,
size_t limit = 0) const {
std::unique_ptr<std::vector<Element*>> result
@ -916,7 +930,7 @@ namespace triagens {
uint64_t hashByKey = _hashElement(element, true);
Bucket const& b = _buckets[hashByKey & _bucketsMask];
uint64_t hashByElm;
IndexType i = findElementPlace(b, element, true, hashByElm);
IndexType i = findElementPlace(userData, b, element, true, hashByElm);
if (b._table[i].ptr == nullptr) {
// This can only happen if the element was the first in its doubly
// linked list (after all, the caller guaranteed that element was
@ -961,16 +975,18 @@ namespace triagens {
////////////////////////////////////////////////////////////////////////////////
std::vector<Element*>* lookupByKeyContinue (
UserData* userData,
Element const* element,
size_t limit = 0) const {
return lookupWithElementByKeyContinue(element, limit);
return lookupWithElementByKeyContinue(userData, element, limit);
}
////////////////////////////////////////////////////////////////////////////////
/// @brief removes an element from the array, caller is responsible to free it
////////////////////////////////////////////////////////////////////////////////
Element* remove (Element const* element) {
Element* remove (UserData* userData,
Element const* element) {
IndexType j = 0;
#ifdef TRI_INTERNAL_STATS
@ -979,10 +995,10 @@ namespace triagens {
#endif
#ifdef TRI_CHECK_MULTI_POINTER_HASH
check(true, true);
check(userData, true, true);
#endif
Bucket* b;
IndexType i = lookupByElement(element, b);
IndexType i = lookupByElement(userData, element, b);
if (b->_table[i].ptr == nullptr) {
return nullptr;
}
@ -997,9 +1013,9 @@ namespace triagens {
// the hole:
invalidateEntry(*b, i);
#ifdef TRI_CHECK_MULTI_POINTER_HASH
check(false, false);
check(userData, false, false);
#endif
healHole(*b, i);
healHole(userData, *b, i);
// this element did not create a collision
}
else {
@ -1012,9 +1028,9 @@ namespace triagens {
_hashElement(b->_table[i].ptr, true));
}
#ifdef TRI_CHECK_MULTI_POINTER_HASH
check(false, false);
check(userData, false, false);
#endif
healHole(*b, j);
healHole(userData, *b, j);
b->_nrCollisions--; // one collision less
}
}
@ -1029,14 +1045,14 @@ namespace triagens {
}
invalidateEntry(*b, i);
#ifdef TRI_CHECK_MULTI_POINTER_HASH
check(false, false);
check(userData, false, false);
#endif
healHole(*b, i);
healHole(userData, *b, i);
b->_nrCollisions--;
}
b->_nrUsed--;
#ifdef TRI_CHECK_MULTI_POINTER_HASH
check(true, true);
check(userData, true, true);
#endif
// return success
return old;
@ -1046,7 +1062,7 @@ namespace triagens {
/// @brief resize the array
////////////////////////////////////////////////////////////////////////////////
int resize (size_t size) noexcept {
int resize (UserData* userData, size_t size) noexcept {
size /= _buckets.size();
for (auto& b : _buckets) {
if (2 * (2 * size + 1) < 3 * b._nrUsed) {
@ -1054,7 +1070,7 @@ namespace triagens {
}
try {
resizeInternal(b, 2 * size + 1);
resizeInternal(userData, b, 2 * size + 1);
}
catch (...) {
return TRI_ERROR_OUT_OF_MEMORY;
@ -1088,11 +1104,11 @@ namespace triagens {
/// function is called on the Element* for each thingy stored in the hash
////////////////////////////////////////////////////////////////////////////////
void iterate (std::function<void(Element*)> callback) {
void iterate (UserData* userData, std::function<void(Element*)> callback) {
for (auto& b : _buckets) {
for (IndexType i = 0; i < b._nrAlloc; i++) {
if (b._table[i].ptr != nullptr) {
callback(b._table[i].ptr);
callback(userData, b._table[i].ptr);
}
}
}
@ -1117,7 +1133,7 @@ namespace triagens {
/// @brief resize the array, internal method
////////////////////////////////////////////////////////////////////////////////
void resizeInternal (Bucket& b, size_t size) {
void resizeInternal (UserData* userData, Bucket& b, size_t size) {
LOG_ACTION("index-resize %s, target size: %llu",
_contextCallback().c_str(),
(unsigned long long) size);
@ -1171,7 +1187,7 @@ namespace triagens {
else {
hashByKey = _hashElement(oldTable[j].ptr, true);
}
IndexType insertPosition = insertFirst(b, oldTable[j].ptr, hashByKey);
IndexType insertPosition = insertFirst(userData, b, oldTable[j].ptr, hashByKey);
// Now walk to the end of the list:
IndexType k = j;
while (oldTable[k].next != INVALID_INDEX) {
@ -1186,7 +1202,7 @@ namespace triagens {
else {
hashByElm = _hashElement(oldTable[k].ptr, false);
}
insertFurther(b, oldTable[k].ptr, hashByKey, hashByElm, insertPosition);
insertFurther(userData, b, oldTable[k].ptr, hashByKey, hashByElm, insertPosition);
k = oldTable[k].prev;
}
}
@ -1206,7 +1222,9 @@ namespace triagens {
/// @brief internal debugging check function
////////////////////////////////////////////////////////////////////////////////
bool check (bool checkCount, bool checkPositions) const {
bool check (UserData* userData,
bool checkCount,
bool checkPositions) const {
std::cout << "Performing AssocMulti check " << checkCount
<< checkPositions << std::endl;
bool ok = true;
@ -1307,7 +1325,8 @@ namespace triagens {
/// @brief find an element or its place using the element hash function
////////////////////////////////////////////////////////////////////////////////
inline IndexType findElementPlace (Bucket const& b,
inline IndexType findElementPlace (UserData* userData,
Bucket const& b,
Element const* element,
bool checkEquality,
uint64_t& hashByElm) const {
@ -1340,7 +1359,8 @@ namespace triagens {
/// @brief find an element or its place by key or element identity
////////////////////////////////////////////////////////////////////////////////
IndexType lookupByElement (Element const* element,
IndexType lookupByElement (UserData* userData,
Element const* element,
Bucket*& buck) const {
// This performs a complete lookup for an element. It returns a slot
// number. This slot is either empty or contains an element that
@ -1371,7 +1391,7 @@ namespace triagens {
// Now we have to look for it in its hash position:
uint64_t hashByElm;
IndexType j = findElementPlace(b, element, true, hashByElm);
IndexType j = findElementPlace(userData, b, element, true, hashByElm);
// We have either found an equal element or nothing:
return j;
@ -1432,7 +1452,7 @@ namespace triagens {
/// @brief helper to heal a hole where we deleted something
////////////////////////////////////////////////////////////////////////////////
void healHole (Bucket& b, IndexType i) {
void healHole (UserData* userData, Bucket& b, IndexType i) {
IndexType j = incr(b, i);
while (b._table[j].ptr != nullptr) {