mirror of https://gitee.com/bigwinds/arangodb
Merge branch 'devel' of https://github.com/arangodb/arangodb into devel
This commit is contained in:
commit
97ce16d88b
|
@ -49,7 +49,7 @@ struct TraverserOptions;
|
||||||
class TraverserEngine {
|
class TraverserEngine {
|
||||||
|
|
||||||
friend class TraverserEngineRegistry;
|
friend class TraverserEngineRegistry;
|
||||||
private:
|
protected:
|
||||||
// These are private on purpose.
|
// These are private on purpose.
|
||||||
// Only the Registry (friend) is allowed
|
// Only the Registry (friend) is allowed
|
||||||
// to create and destroy engines.
|
// to create and destroy engines.
|
||||||
|
@ -61,7 +61,6 @@ class TraverserEngine {
|
||||||
public:
|
public:
|
||||||
virtual ~TraverserEngine();
|
virtual ~TraverserEngine();
|
||||||
|
|
||||||
public:
|
|
||||||
// The engine is NOT copyable.
|
// The engine is NOT copyable.
|
||||||
TraverserEngine(TraverserEngine const&) = delete;
|
TraverserEngine(TraverserEngine const&) = delete;
|
||||||
|
|
||||||
|
|
|
@ -28,6 +28,7 @@
|
||||||
#include "Basics/AssocMulti.h"
|
#include "Basics/AssocMulti.h"
|
||||||
#include "Basics/AssocUnique.h"
|
#include "Basics/AssocUnique.h"
|
||||||
#include "Basics/VelocyPackHelper.h"
|
#include "Basics/VelocyPackHelper.h"
|
||||||
|
#include "Basics/fasthash.h"
|
||||||
#include "Indexes/PathBasedIndex.h"
|
#include "Indexes/PathBasedIndex.h"
|
||||||
#include "Indexes/IndexIterator.h"
|
#include "Indexes/IndexIterator.h"
|
||||||
#include "Utils/Transaction.h"
|
#include "Utils/Transaction.h"
|
||||||
|
|
|
@ -986,7 +986,9 @@ void Transaction::extractKeyAndRevFromDocument(VPackSlice slice,
|
||||||
VPackSlice revSlice(p + 1);
|
VPackSlice revSlice(p + 1);
|
||||||
if (revSlice.isString()) {
|
if (revSlice.isString()) {
|
||||||
bool isOld;
|
bool isOld;
|
||||||
revisionId = TRI_StringToRid(revSlice.copyString(), isOld);
|
VPackValueLength l;
|
||||||
|
char const* p = revSlice.getString(l);
|
||||||
|
revisionId = TRI_StringToRid(p, l, isOld);
|
||||||
} else if (revSlice.isNumber()) {
|
} else if (revSlice.isNumber()) {
|
||||||
revisionId = revSlice.getNumericValue<TRI_voc_rid_t>();
|
revisionId = revSlice.getNumericValue<TRI_voc_rid_t>();
|
||||||
}
|
}
|
||||||
|
@ -1002,10 +1004,48 @@ void Transaction::extractKeyAndRevFromDocument(VPackSlice slice,
|
||||||
}
|
}
|
||||||
|
|
||||||
// fall back to regular lookup
|
// fall back to regular lookup
|
||||||
|
{
|
||||||
keySlice = slice.get(StaticStrings::KeyString);
|
keySlice = slice.get(StaticStrings::KeyString);
|
||||||
bool isOld;
|
bool isOld;
|
||||||
revisionId = TRI_StringToRid(slice.get(StaticStrings::RevString).copyString(),
|
VPackValueLength l;
|
||||||
isOld);
|
char const* p = slice.get(StaticStrings::RevString).getString(l);
|
||||||
|
revisionId = TRI_StringToRid(p, l, isOld);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief extract _rev from a database document
|
||||||
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
TRI_voc_rid_t Transaction::extractRevFromDocument(VPackSlice slice) {
|
||||||
|
TRI_ASSERT(slice.isObject());
|
||||||
|
TRI_ASSERT(slice.length() >= 2);
|
||||||
|
|
||||||
|
uint8_t const* p = slice.begin() + slice.findDataOffset(slice.head());
|
||||||
|
VPackValueLength count = 0;
|
||||||
|
|
||||||
|
while (*p <= basics::VelocyPackHelper::ToAttribute && ++count <= 5) {
|
||||||
|
if (*p == basics::VelocyPackHelper::RevAttribute) {
|
||||||
|
VPackSlice revSlice(p + 1);
|
||||||
|
if (revSlice.isString()) {
|
||||||
|
bool isOld;
|
||||||
|
VPackValueLength l;
|
||||||
|
char const* p = revSlice.getString(l);
|
||||||
|
return TRI_StringToRid(p, l, isOld);
|
||||||
|
} else if (revSlice.isNumber()) {
|
||||||
|
return revSlice.getNumericValue<TRI_voc_rid_t>();
|
||||||
|
}
|
||||||
|
// invalid type for revision id
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
// skip over the attribute name
|
||||||
|
++p;
|
||||||
|
// skip over the attribute value
|
||||||
|
p += VPackSlice(p).byteSize();
|
||||||
|
}
|
||||||
|
|
||||||
|
TRI_ASSERT(false);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
|
@ -360,6 +360,12 @@ class Transaction {
|
||||||
VPackSlice& keySlice,
|
VPackSlice& keySlice,
|
||||||
TRI_voc_rid_t& revisionId);
|
TRI_voc_rid_t& revisionId);
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief extract _rev from a database document
|
||||||
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
static TRI_voc_rid_t extractRevFromDocument(VPackSlice slice);
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
/// @brief read any (random) document
|
/// @brief read any (random) document
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
#include "Aql/QueryResultV8.h"
|
#include "Aql/QueryResultV8.h"
|
||||||
#include "Basics/StaticStrings.h"
|
#include "Basics/StaticStrings.h"
|
||||||
#include "Basics/VelocyPackHelper.h"
|
#include "Basics/VelocyPackHelper.h"
|
||||||
|
#include "Basics/fasthash.h"
|
||||||
#include "Indexes/GeoIndex.h"
|
#include "Indexes/GeoIndex.h"
|
||||||
#include "Utils/OperationCursor.h"
|
#include "Utils/OperationCursor.h"
|
||||||
#include "Utils/SingleCollectionTransaction.h"
|
#include "Utils/SingleCollectionTransaction.h"
|
||||||
|
|
|
@ -1913,7 +1913,9 @@ int LogicalCollection::update(Transaction* trx, VPackSlice const newSlice,
|
||||||
return TRI_ERROR_ARANGO_DOCUMENT_REV_BAD;
|
return TRI_ERROR_ARANGO_DOCUMENT_REV_BAD;
|
||||||
}
|
}
|
||||||
bool isOld;
|
bool isOld;
|
||||||
revisionId = TRI_StringToRid(oldRev.copyString(), isOld);
|
VPackValueLength l;
|
||||||
|
char const* p = oldRev.getString(l);
|
||||||
|
revisionId = TRI_StringToRid(p, l, isOld);
|
||||||
if (isOld) {
|
if (isOld) {
|
||||||
// Do not tolerate old revision IDs
|
// Do not tolerate old revision IDs
|
||||||
revisionId = TRI_HybridLogicalClock();
|
revisionId = TRI_HybridLogicalClock();
|
||||||
|
@ -2067,7 +2069,9 @@ int LogicalCollection::replace(Transaction* trx, VPackSlice const newSlice,
|
||||||
return TRI_ERROR_ARANGO_DOCUMENT_REV_BAD;
|
return TRI_ERROR_ARANGO_DOCUMENT_REV_BAD;
|
||||||
}
|
}
|
||||||
bool isOld;
|
bool isOld;
|
||||||
revisionId = TRI_StringToRid(oldRev.copyString(), isOld);
|
VPackValueLength l;
|
||||||
|
char const* p = oldRev.getString(l);
|
||||||
|
revisionId = TRI_StringToRid(p, l, isOld);
|
||||||
if (isOld) {
|
if (isOld) {
|
||||||
// Do not tolerate old revision ticks:
|
// Do not tolerate old revision ticks:
|
||||||
revisionId = TRI_HybridLogicalClock();
|
revisionId = TRI_HybridLogicalClock();
|
||||||
|
@ -2183,7 +2187,9 @@ int LogicalCollection::remove(arangodb::Transaction* trx,
|
||||||
revisionId = TRI_HybridLogicalClock();
|
revisionId = TRI_HybridLogicalClock();
|
||||||
} else {
|
} else {
|
||||||
bool isOld;
|
bool isOld;
|
||||||
revisionId = TRI_StringToRid(oldRev.copyString(), isOld);
|
VPackValueLength l;
|
||||||
|
char const* p = oldRev.getString(l);
|
||||||
|
revisionId = TRI_StringToRid(p, l, isOld);
|
||||||
if (isOld) {
|
if (isOld) {
|
||||||
// Do not tolerate old revisions
|
// Do not tolerate old revisions
|
||||||
revisionId = TRI_HybridLogicalClock();
|
revisionId = TRI_HybridLogicalClock();
|
||||||
|
@ -3090,7 +3096,9 @@ int LogicalCollection::newObjectForInsert(
|
||||||
return TRI_ERROR_ARANGO_DOCUMENT_REV_BAD;
|
return TRI_ERROR_ARANGO_DOCUMENT_REV_BAD;
|
||||||
}
|
}
|
||||||
bool isOld;
|
bool isOld;
|
||||||
TRI_voc_rid_t oldRevision = TRI_StringToRid(oldRev.copyString(), isOld);
|
VPackValueLength l;
|
||||||
|
char const* p = oldRev.getString(l);
|
||||||
|
TRI_voc_rid_t oldRevision = TRI_StringToRid(p, l, isOld);
|
||||||
if (isOld) {
|
if (isOld) {
|
||||||
oldRevision = TRI_HybridLogicalClock();
|
oldRevision = TRI_HybridLogicalClock();
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,7 +26,7 @@
|
||||||
|
|
||||||
#include "Basics/Common.h"
|
#include "Basics/Common.h"
|
||||||
#include "Basics/StaticStrings.h"
|
#include "Basics/StaticStrings.h"
|
||||||
#include "Basics/fasthash.h"
|
#include "Utils/Transaction.h"
|
||||||
#include "VocBase/DatafileHelper.h"
|
#include "VocBase/DatafileHelper.h"
|
||||||
#include "VocBase/voc-types.h"
|
#include "VocBase/voc-types.h"
|
||||||
|
|
||||||
|
@ -152,7 +152,7 @@ struct TRI_doc_mptr_t {
|
||||||
|
|
||||||
// return the marker's revision id as string slice or None slice if not there
|
// return the marker's revision id as string slice or None slice if not there
|
||||||
TRI_voc_rid_t revisionId() const {
|
TRI_voc_rid_t revisionId() const {
|
||||||
return TRI_ExtractRevisionId(VPackSlice(vpack()));
|
return arangodb::Transaction::extractRevFromDocument(VPackSlice(vpack()));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -53,6 +53,7 @@ bool DepthFirstEnumerator::next() {
|
||||||
_edgeCursors.emplace(cursor);
|
_edgeCursors.emplace(cursor);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
TRI_ASSERT(!_enumeratedPath.edges.empty());
|
||||||
// This path is at the end. cut the last step
|
// This path is at the end. cut the last step
|
||||||
_enumeratedPath.vertices.pop_back();
|
_enumeratedPath.vertices.pop_back();
|
||||||
_enumeratedPath.edges.pop_back();
|
_enumeratedPath.edges.pop_back();
|
||||||
|
@ -70,6 +71,7 @@ bool DepthFirstEnumerator::next() {
|
||||||
_returnedEdges.emplace(_enumeratedPath.edges.back());
|
_returnedEdges.emplace(_enumeratedPath.edges.back());
|
||||||
} else {
|
} else {
|
||||||
_traverser->_filteredPaths++;
|
_traverser->_filteredPaths++;
|
||||||
|
TRI_ASSERT(!_enumeratedPath.edges.empty());
|
||||||
_enumeratedPath.edges.pop_back();
|
_enumeratedPath.edges.pop_back();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -79,6 +81,7 @@ bool DepthFirstEnumerator::next() {
|
||||||
_enumeratedPath.edges.size() - 1,
|
_enumeratedPath.edges.size() - 1,
|
||||||
cursorId)) {
|
cursorId)) {
|
||||||
// This edge does not pass the filtering
|
// This edge does not pass the filtering
|
||||||
|
TRI_ASSERT(!_enumeratedPath.edges.empty());
|
||||||
_enumeratedPath.edges.pop_back();
|
_enumeratedPath.edges.pop_back();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -98,6 +101,7 @@ bool DepthFirstEnumerator::next() {
|
||||||
if (!foundOnce) {
|
if (!foundOnce) {
|
||||||
// We found it and it was not the last element (expected)
|
// We found it and it was not the last element (expected)
|
||||||
// This edge is allready on the path
|
// This edge is allready on the path
|
||||||
|
TRI_ASSERT(!_enumeratedPath.edges.empty());
|
||||||
_enumeratedPath.edges.pop_back();
|
_enumeratedPath.edges.pop_back();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -123,6 +127,7 @@ bool DepthFirstEnumerator::next() {
|
||||||
if (!foundOnce) {
|
if (!foundOnce) {
|
||||||
// We found it and it was not the last element (expected)
|
// We found it and it was not the last element (expected)
|
||||||
// This vertex is allready on the path
|
// This vertex is allready on the path
|
||||||
|
TRI_ASSERT(!_enumeratedPath.edges.empty());
|
||||||
_enumeratedPath.vertices.pop_back();
|
_enumeratedPath.vertices.pop_back();
|
||||||
_enumeratedPath.edges.pop_back();
|
_enumeratedPath.edges.pop_back();
|
||||||
continue;
|
continue;
|
||||||
|
@ -136,15 +141,18 @@ bool DepthFirstEnumerator::next() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
// Vertex Invalid. Revoke edge
|
// Vertex Invalid. Revoke edge
|
||||||
|
TRI_ASSERT(!_enumeratedPath.edges.empty());
|
||||||
_enumeratedPath.edges.pop_back();
|
_enumeratedPath.edges.pop_back();
|
||||||
continue;
|
continue;
|
||||||
} else {
|
} else {
|
||||||
// cursor is empty.
|
// cursor is empty.
|
||||||
_edgeCursors.pop();
|
_edgeCursors.pop();
|
||||||
|
if (!_enumeratedPath.edges.empty()) {
|
||||||
_enumeratedPath.edges.pop_back();
|
_enumeratedPath.edges.pop_back();
|
||||||
_enumeratedPath.vertices.pop_back();
|
_enumeratedPath.vertices.pop_back();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if (_edgeCursors.empty()) {
|
if (_edgeCursors.empty()) {
|
||||||
// If we get here all cursors are exhausted.
|
// If we get here all cursors are exhausted.
|
||||||
_enumeratedPath.edges.clear();
|
_enumeratedPath.edges.clear();
|
||||||
|
|
|
@ -1250,7 +1250,9 @@ TRI_voc_rid_t TRI_ExtractRevisionId(VPackSlice slice) {
|
||||||
VPackSlice r(slice.get(StaticStrings::RevString));
|
VPackSlice r(slice.get(StaticStrings::RevString));
|
||||||
if (r.isString()) {
|
if (r.isString()) {
|
||||||
bool isOld;
|
bool isOld;
|
||||||
return TRI_StringToRid(r.copyString(), isOld);
|
VPackValueLength l;
|
||||||
|
char const* p = r.getString(l);
|
||||||
|
return TRI_StringToRid(p, l, isOld);
|
||||||
}
|
}
|
||||||
if (r.isInteger()) {
|
if (r.isInteger()) {
|
||||||
return r.getNumber<TRI_voc_rid_t>();
|
return r.getNumber<TRI_voc_rid_t>();
|
||||||
|
@ -1325,7 +1327,15 @@ TRI_voc_rid_t TRI_StringToRid(char const* p, size_t len, bool& isOld) {
|
||||||
if (len > 0 && *p >= '1' && *p <= '9') {
|
if (len > 0 && *p >= '1' && *p <= '9') {
|
||||||
// Remove this case before the year 3887 AD because then it will
|
// Remove this case before the year 3887 AD because then it will
|
||||||
// start to clash with encoded timestamps:
|
// start to clash with encoded timestamps:
|
||||||
TRI_voc_rid_t r = arangodb::basics::StringUtils::uint64(p, len);
|
char const* e = p + len;
|
||||||
|
TRI_voc_rid_t r = 0;
|
||||||
|
do {
|
||||||
|
r += *p - '0';
|
||||||
|
if (++p == e) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
r *= 10;
|
||||||
|
} while (true);
|
||||||
if (r > tickLimit) {
|
if (r > tickLimit) {
|
||||||
// An old tick value that could be confused with a time stamp
|
// An old tick value that could be confused with a time stamp
|
||||||
LOG(WARN)
|
LOG(WARN)
|
||||||
|
|
|
@ -38,7 +38,9 @@ struct DocumentOperation {
|
||||||
TRI_ASSERT(marker != nullptr);
|
TRI_ASSERT(marker != nullptr);
|
||||||
VPackSlice s(static_cast<uint8_t*>(marker->vpack()));
|
VPackSlice s(static_cast<uint8_t*>(marker->vpack()));
|
||||||
bool isOld;
|
bool isOld;
|
||||||
rid = TRI_StringToRid(s.get(StaticStrings::RevString).copyString(), isOld);
|
VPackValueLength l;
|
||||||
|
char const* p = s.get(StaticStrings::RevString).getString(l);
|
||||||
|
rid = TRI_StringToRid(p, l, isOld);
|
||||||
}
|
}
|
||||||
|
|
||||||
~DocumentOperation() {
|
~DocumentOperation() {
|
||||||
|
|
Loading…
Reference in New Issue