mirror of https://gitee.com/bigwinds/arangodb
Merge branch 'spdvpk' of https://github.com/arangodb/arangodb into spdvpk
This commit is contained in:
commit
7efe1c6091
|
@ -220,6 +220,7 @@ add_executable(
|
|||
Utils/Cursor.cpp
|
||||
Utils/CursorRepository.cpp
|
||||
Utils/DocumentHelper.cpp
|
||||
Utils/OperationCursor.cpp
|
||||
Utils/ShapedJsonTransformer.cpp
|
||||
Utils/StandaloneTransactionContext.cpp
|
||||
Utils/Transaction.cpp
|
||||
|
|
|
@ -0,0 +1,66 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// DISCLAIMER
|
||||
///
|
||||
/// Copyright 2014-2016 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 Michael Hackstein
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "OperationCursor.h"
|
||||
|
||||
using namespace arangodb;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Get next default batchSize many elements.
|
||||
/// Check hasMore()==true before using this
|
||||
/// NOTE: This will throw on OUT_OF_MEMORY
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
int OperationCursor::getMore() {
|
||||
return getMore(_batchSize);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Get next batchSize many elements.
|
||||
/// Check hasMore()==true before using this
|
||||
/// NOTE: This will throw on OUT_OF_MEMORY
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
int OperationCursor::getMore(uint64_t batchSize) {
|
||||
// This may throw out of memory
|
||||
if (!hasMore()) {
|
||||
TRI_ASSERT(false);
|
||||
// You requested more even if you should have checked it before.
|
||||
return TRI_ERROR_FORBIDDEN;
|
||||
}
|
||||
// We restart the builder
|
||||
_builder.clear();
|
||||
VPackArrayBuilder guard(&_builder);
|
||||
TRI_doc_mptr_t* mptr = nullptr;
|
||||
// TODO: Improve this for baby awareness
|
||||
while (batchSize > 0 && _limit > 0 && (mptr = _indexIterator->next()) != nullptr) {
|
||||
--batchSize;
|
||||
--_limit;
|
||||
_builder.add(VPackSlice(mptr->vpack()));
|
||||
}
|
||||
if (batchSize > 0 || _limit == 0) {
|
||||
// Iterator empty, there is no more
|
||||
_hasMore = false;
|
||||
}
|
||||
return TRI_ERROR_NO_ERROR;
|
||||
}
|
|
@ -81,6 +81,10 @@ struct OperationCursor : public OperationResult {
|
|||
|
||||
~OperationCursor() {
|
||||
}
|
||||
|
||||
IndexIterator* indexIterator() const {
|
||||
return _indexIterator.get();
|
||||
}
|
||||
|
||||
bool hasMore() const {
|
||||
return _hasMore;
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
|
||||
#include <velocypack/Builder.h>
|
||||
#include <velocypack/Collection.h>
|
||||
#include <velocypack/Options.h>
|
||||
#include <velocypack/Slice.h>
|
||||
#include <velocypack/velocypack-aliases.h>
|
||||
|
||||
|
@ -1362,6 +1363,10 @@ OperationResult Transaction::allLocal(std::string const& collectionName,
|
|||
return OperationResult(TRI_ERROR_ARANGO_COLLECTION_NOT_FOUND);
|
||||
}
|
||||
|
||||
if (orderDitch(trxCollection(cid)) == nullptr) {
|
||||
return OperationResult(TRI_ERROR_OUT_OF_MEMORY);
|
||||
}
|
||||
|
||||
int res = lock(trxCollection(cid), TRI_TRANSACTION_READ);
|
||||
|
||||
if (res != TRI_ERROR_NO_ERROR) {
|
||||
|
@ -1433,8 +1438,63 @@ OperationResult Transaction::truncateCoordinator(std::string const& collectionNa
|
|||
|
||||
OperationResult Transaction::truncateLocal(std::string const& collectionName,
|
||||
OperationOptions& options) {
|
||||
// TODO
|
||||
THROW_ARANGO_EXCEPTION(TRI_ERROR_NOT_IMPLEMENTED);
|
||||
TRI_voc_cid_t cid = resolver()->getCollectionIdLocal(collectionName);
|
||||
|
||||
if (cid == 0) {
|
||||
return OperationResult(TRI_ERROR_ARANGO_COLLECTION_NOT_FOUND);
|
||||
}
|
||||
|
||||
if (orderDitch(trxCollection(cid)) == nullptr) {
|
||||
return OperationResult(TRI_ERROR_OUT_OF_MEMORY);
|
||||
}
|
||||
|
||||
int res = lock(trxCollection(cid), TRI_TRANSACTION_WRITE);
|
||||
|
||||
if (res != TRI_ERROR_NO_ERROR) {
|
||||
return OperationResult(res);
|
||||
}
|
||||
|
||||
TRI_document_collection_t* document = documentCollection(trxCollection(cid));
|
||||
|
||||
TRI_voc_rid_t actualRevision = 0;
|
||||
TRI_doc_update_policy_t updatePolicy(TRI_DOC_UPDATE_LAST_WRITE, 0, &actualRevision);
|
||||
|
||||
VPackBuilder keyBuilder;
|
||||
auto primaryIndex = document->primaryIndex();
|
||||
|
||||
std::function<void(TRI_doc_mptr_t*)> callback = [this, &document, &keyBuilder, &updatePolicy, &options](TRI_doc_mptr_t const* mptr) {
|
||||
VPackSlice slice(mptr->vpack());
|
||||
VPackSlice keySlice = slice.get(TRI_VOC_ATTRIBUTE_KEY);
|
||||
|
||||
keyBuilder.clear();
|
||||
keyBuilder.openObject();
|
||||
keyBuilder.add(TRI_VOC_ATTRIBUTE_KEY, keySlice);
|
||||
keyBuilder.close();
|
||||
|
||||
VPackSlice builderSlice = keyBuilder.slice();
|
||||
|
||||
int res = document->remove(this, &builderSlice, &updatePolicy, options, false);
|
||||
|
||||
if (res != TRI_ERROR_NO_ERROR) {
|
||||
THROW_ARANGO_EXCEPTION(res);
|
||||
}
|
||||
};
|
||||
|
||||
try {
|
||||
primaryIndex->invokeOnAllElements(callback);
|
||||
}
|
||||
catch (basics::Exception const& ex) {
|
||||
unlock(trxCollection(cid), TRI_TRANSACTION_WRITE);
|
||||
return OperationResult(ex.code());
|
||||
}
|
||||
|
||||
res = unlock(trxCollection(cid), TRI_TRANSACTION_WRITE);
|
||||
|
||||
if (res != TRI_ERROR_NO_ERROR) {
|
||||
return OperationCursor(res);
|
||||
}
|
||||
|
||||
return OperationResult(TRI_ERROR_NO_ERROR);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -1554,6 +1614,7 @@ OperationCursor Transaction::indexScan(
|
|||
"Could not find primary index in collection '" + collectionName + "'.");
|
||||
}
|
||||
|
||||
LOG(INFO) << "reverse: " << reverse;
|
||||
iterator.reset(idx->allIterator(this, reverse));
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -890,11 +890,11 @@ static void JS_AllQuery(v8::FunctionCallbackInfo<v8::Value> const& args) {
|
|||
std::string collectionName(col->_name);
|
||||
|
||||
// We directly read the entire cursor. so batchsize == limit
|
||||
OperationResult opRes = trx.indexScan(collectionName, Transaction::CursorType::ALL, "", {}, skip, limit, limit, false);
|
||||
OperationCursor opCursor = trx.indexScan(collectionName, Transaction::CursorType::ALL, "", {}, skip, limit, limit, false);
|
||||
|
||||
if (opRes.failed()) {
|
||||
trx.finish(opRes.code);
|
||||
TRI_V8_THROW_EXCEPTION(opRes.code);
|
||||
if (opCursor.failed()) {
|
||||
trx.finish(opCursor.code);
|
||||
TRI_V8_THROW_EXCEPTION(opCursor.code);
|
||||
}
|
||||
|
||||
OperationResult countResult = trx.count(collectionName);
|
||||
|
@ -912,9 +912,18 @@ static void JS_AllQuery(v8::FunctionCallbackInfo<v8::Value> const& args) {
|
|||
TRI_ASSERT(count.isNumber());
|
||||
|
||||
VPackOptions resultOptions = VPackOptions::Defaults;
|
||||
resultOptions.customTypeHandler = opRes.customTypeHandler;
|
||||
resultOptions.customTypeHandler = opCursor.customTypeHandler;
|
||||
|
||||
VPackSlice docs = opRes.slice();
|
||||
if (!opCursor.hasMore()) {
|
||||
// OUT OF MEMORY. initial hasMore should return true even if index is empty
|
||||
TRI_V8_THROW_EXCEPTION(TRI_ERROR_OUT_OF_MEMORY);
|
||||
}
|
||||
|
||||
opCursor.getMore();
|
||||
// We only need this one call, limit == batchsize
|
||||
|
||||
VPackSlice docs = opCursor.slice();
|
||||
TRI_ASSERT(docs.isArray());
|
||||
// setup result
|
||||
v8::Handle<v8::Object> result = v8::Object::New(isolate);
|
||||
auto documents = TRI_VPackToV8(isolate, docs, &resultOptions);
|
||||
|
|
|
@ -330,6 +330,10 @@ class AssocUnique {
|
|||
}
|
||||
|
||||
public:
|
||||
size_t buckets() const {
|
||||
return _buckets.size();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief checks if this index is empty
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -839,7 +843,8 @@ class AssocUnique {
|
|||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief a method to iterate over all elements in the hash
|
||||
/// @brief a method to iterate over all elements in the hash. this method
|
||||
/// can be used for deleting elements as well
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void invokeOnAllElements(CallbackElementFuncType callback) {
|
||||
|
@ -847,11 +852,16 @@ class AssocUnique {
|
|||
if (b._table == nullptr) {
|
||||
continue;
|
||||
}
|
||||
for (size_t i = 0; i < b._nrAlloc; ++i) {
|
||||
for (size_t i = 0; i < b._nrAlloc; /* no hoisting */) {
|
||||
if (b._table[i] == nullptr) {
|
||||
++i;
|
||||
continue;
|
||||
}
|
||||
// don't increment i
|
||||
callback(b._table[i]);
|
||||
if (b._nrUsed == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue