8000 Merge branch 'devel' of https://github.com/arangodb/arangodb into fea… · arangodb/arangodb@7f67ae6 · GitHub
[go: up one dir, main page]

Skip to content

Commit 7f67ae6

Browse files
committed
Merge branch 'devel' of https://github.com/arangodb/arangodb into feature/one-shard-clean-up-2
* 'devel' of https://github.com/arangodb/arangodb: Bug fix/improve stringutils performance (#10208) add option to talk to the SUT using VST (#10217) Doc - Added "log-output" example (#10207) fix it! (#10198) add missing include Bug fix/fix simple example dep proxy skip some regression test (#10213) fixed ui behaviour when replacing a foxx app (#9719) [devel] Fix document search (Ctrl+F/Cmd+F) (#10216) Convert many uses of ClusterComm to Fuerte (#10154) Remove invokeOnAllElements (#10212) AQL Subquery: MultiDependencyRowFetcher (#10101) Bug fix/fix remote executor races (#10206) fix several inefficiencies in Store (#10189) Deprecate rocksdb.max-write-buffer-number startup option (#9654) fix arangosh with vst
2 parents 5279597 + 4667483 commit 7f67ae6

File tree

167 files changed

+3457
-2829
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

167 files changed

+3457
-2829
lines changed

3rdParty/fuerte/include/fuerte/detail/vst.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,7 @@ RequestHeader requestHeaderFromSlice(velocypack::Slice const& header);
142142
/// creates a RequestHeader from a given slice
143143
ResponseHeader responseHeaderFromSlice(velocypack::Slice const& header);
144144

145-
// Validates if payload consitsts of valid velocypack slices
145+
// Validates if payload consists of valid velocypack slices
146146
std::size_t validateAndCount(uint8_t const* vpHeaderStart, std::size_t len);
147147

148148
} // namespace parser

3rdParty/fuerte/include/fuerte/message.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -70,8 +70,8 @@ struct MessageHeader {
7070
protected:
7171
StringMap _meta; /// Header meta data (equivalent to HTTP headers)
7272
short _version;
73-
ContentType _contentType;
74-
ContentType _acceptType;
73+
ContentType _contentType = ContentType::Unset;
74+
ContentType _acceptType = ContentType::Unset;
7575
};
7676

7777
struct RequestHeader final : public MessageHeader {
@@ -91,6 +91,7 @@ struct RequestHeader final : public MessageHeader {
9191
// accept header accessors
9292
ContentType acceptType() const { return _acceptType; }
9393
void acceptType(ContentType type) { _acceptType = type; }
94+
void acceptType(std::string const& type) { _acceptType = to_ContentType(type); }
9495

9596
// query parameter helpers
9697
void addParameter(std::string const& key, std::string const& value);
@@ -207,7 +208,7 @@ class Request final : public Message {
207208
};
208209

209210
// Response contains the message resulting from a request to a server.
210-
class Response final : public Message {
211+
class Response : public Message {
211212
public:
212213
Response(ResponseHeader reqHeader = ResponseHeader())
213214
: header(std::move(reqHeader)), _payloadOffset(0) {}

3rdParty/fuerte/include/fuerte/types.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ std::string to_string(ProtocolType type);
145145
// --SECTION-- ContentType
146146
// -----------------------------------------------------------------------------
147147

148-
enum class ContentType { Unset, Custom, VPack, Dump, Json, Html, Text, BatchPart, FormData };
148+
enum class ContentType { Unset = 0, Custom, VPack, Dump, Json, Html, Text, BatchPart, FormData };
149149
ContentType to_ContentType(std::string const& val);
150150
std::string to_string(ContentType type);
151151

3rdParty/fuerte/src/vst.cpp

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -170,8 +170,6 @@ void message::requestHeader(RequestHeader const& header,
170170
/// @brief creates a slice containing a VST response-message header.
171171
void message::responseHeader(ResponseHeader const& header,
172172
VPackBuffer<uint8_t>& buffer) {
173-
static std::string const message = " for message not set";
174-
175173
VPackBuilder builder(buffer);
176174
assert(builder.isClosed());
177175
builder.openArray();
@@ -505,7 +503,6 @@ ResponseHeader responseHeaderFromSlice(VPackSlice const& headerSlice) {
505503
assert(headerSlice.at(1).getNumber<int>() ==
506504
static_cast<int>(MessageType::Response));
507505
header.responseCode = headerSlice.at(2).getNumber<StatusCode>();
508-
// header.contentType(ContentType::VPack); // empty meta
509506
if (headerSlice.length() >= 4) {
510507
VPackSlice meta = headerSlice.at(3);
511508
assert(meta.isObject());
@@ -521,9 +518,9 @@ ResponseHeader responseHeaderFromSlice(VPackSlice const& headerSlice) {
521518
header.contentType(ContentType::VPack);
522519
}
523520
return header;
524-
};
521+
}
525522

526-
// Validates if payload consitsts of valid velocypack slices
523+
// Validates if payload consists of valid velocypack slices
527524
std::size_t validateAndCount(uint8_t const* const vpStart, std::size_t length) {
528525
// start points to the begin of a velocypack
529526
uint8_t const* cursor = vpStart;

CHANGELOG

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
11
devel
22
-----
33

4-
* Bugfix: In an AQL cluster query, when gathering unsorted data in combination
5-
with a LIMIT with non-zero offset, if this offset exactly matches the number
6-
of documents in the first shards consumed, the rest of the documents was not
7-
returned.
4+
* Made the mechanism in the Web UI of replacing and upgrading a foxx app more clear.
5+
6+
* Fixed search not working in document view while in code mode
87

98
* Show shards of all collections (including system collections) in the web UI's shard
109
distribution view.

arangod/Actions/actions.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ std::shared_ptr<TRI_action_t> TRI_DefineActionVocBase(std::string const& name,
6262
url = url.substr(1);
6363
}
6464

65-
action->setUrl(url, StringUtils::split(url, "/").size());
65+
action->setUrl(url, StringUtils::split(url, '/').size());
6666

6767
std::unordered_map<std::string, std::shared_ptr<TRI_action_t>>* which;
6868

arangod/Agency/AgencyComm.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -927,7 +927,7 @@ bool AgencyComm::exists(std::string const& key) {
927927
return false;
928928
}
929929

930-
auto parts = arangodb::basics::StringUtils::split(key, "/");
930+
auto parts = arangodb::basics::StringUtils::split(key, '/');
931931
std::vector<std::string> allParts;
932932
allParts.reserve(parts.size() + 1);
933933
allParts.push_back(AgencyCommManager::path());

arangod/Agency/Store.cpp

Lines changed: 109 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -37,51 +37,18 @@
3737
#include <velocypack/Buffer.h>
3838
#include <velocypack/Iterator.h>
3939
#include <velocypack/Slice.h>
40+
#include <velocypack/StringRef.h>
4041
#include <velocypack/velocypack-aliases.h>
4142

4243
#include <ctime>
4344
#include <iomanip>
44-
#include <regex>
4545

4646
using namespace arangodb::consensus;
4747
using namespace arangodb::basics;
4848

49-
/// Non-Emptyness of string
50-
struct NotEmpty {
51-
bool operator()(const std::string& s) { return !s.empty(); }
52-
};
53-
54-
/// @brief Split strings by separator
55-
inline static std::vector<std::string> split(const std::string& str, char separator) {
56-
std::vector<std::string> result;
57-
if (str.empty()) {
58-
return result;
59-
}
60-
std::regex reg("/+");
61-
std::string key = std::regex_replace(str, reg, "/");
62-
63-
if (!key.empty() && key.front() == '/') {
64-
key.erase(0, 1);
65-
}
66-
if (!key.empty() && key.back() == '/') {
67-
key.pop_back();
68-
}
69-
70-
std::string::size_type p = 0;
71-
std::string::size_type q;
72-
while ((q = key.find(separator, p)) != std::string::npos) {
73-
result.emplace_back(key, p, q - p);
74-
p = q + 1;
75-
}
76-
result.emplace_back(key, p);
77-
result.erase(std::find_if(result.rbegin(), result.rend(), NotEmpty()).base(),
78-
result.end());
79-
return result;
80-
}
81-
8249
/// Build endpoint from URL
83-
inline static bool endpointPathFromUrl(std::string const& url,
84-
std::string& endpoint, std::string& path) {
50+
static bool endpointPathFromUrl(std::string const& url,
51+
std::string& endpoint, std::string& path) {
8552
std::stringstream ep;
8653
path = "/";
8754
size_t pos = 7;
@@ -405,7 +372,7 @@ check_ret_t Store::check(VPackSlice const& slice, CheckMode mode) const {
405372
for (auto const& precond : VPackObjectIterator(slice)) { // Preconditions
406373

407374
std::string key = precond.key.copyString();
408-
std::vector<std::string> pv = split(key, '/');
375+
std::vector<std::string> pv = split(key);
409376

410377
Node const* node = &Node::dummyNode();
411378

@@ -578,7 +545,7 @@ bool Store::read(VPackSlice const& query, Builder& ret) const {
578545
MUTEX_LOCKER(storeLocker, _storeLock); // Freeze KV-Store for read
579546
if (query_strs.size() == 1) {
580547
auto const& path = query_strs[0];
581-
std::vector<std::string> pv = split(path, '/');
548+
std::vector<std::string> pv = split(path);
582549
// Build surrounding object structure:
583550
size_t e = _node.exists(pv).size(); // note: e <= pv.size()!
584551
size_t i = 0;
@@ -599,7 +566,7 @@ bool Store::read(VPackSlice const& query, Builder& ret) const {
599566
// Create response tree
600567
Node copy("copy");
601568
for (auto const& path : query_strs) {
602-
std::vector<std::string> pv = split(path, '/');
569+
std::vector<std::string> pv = split(path);
603570
size_t e = _node.exists(pv).size();
604571
if (e == pv.size()) { // existing
605572
copy(pv) = _node(pv);
@@ -652,7 +619,7 @@ void Store::dumpToBuilder(Builder& builder) const {
652619
MUTEX_LOCKER(storeLocker, _storeLock);
653620
toBuilder(builder, true);
654621

655-
std::map<std::string, int64_t> clean {};
622+
std::map<std::string, int64_t> clean;
656623
for (auto const& i : _timeTable) {
657624
auto ts = std::chrono::duration_cast<std::chrono::seconds>(
658625
i.first.time_since_epoch()).count();
@@ -688,41 +655,78 @@ void Store::dumpToBuilder(Builder& builder) const {
688655

689656
/// Apply transaction to key value store. Guarded by caller
690657
bool Store::applies(arangodb::velocypack::Slice const& transaction) {
691-
std::vector<std::string> keys;
658+
_storeLock.assertLockedByCurrentThread();
659+
660+
auto it = VPackObjectIterator(transaction);
661+
692662
std::vector<std::string> abskeys;
693-
std::vector<size_t> idx;
694-
std::regex reg("/+");
663+
abskeys.reserve(it.size());
664+
665+
std::vector<std::pair<size_t, VPackSlice>> idx;
666+
idx.reserve(it.size());
667+
695668
size_t counter = 0;
669+
while (it.valid()) {
670+
VPackStringRef key = it.key().stringRef();
671+
672+
// push back an empty string first, so we can avoid a later move
673+
abskeys.emplace_back();
674+
675+
// and now work on this string
676+
std::string& absoluteKey = abskeys.back();
677+
absoluteKey.reserve(key.size());
678+
679+
// turn the path into an absolute path, collapsing all duplicate
680+
// forward slashes into a single forward slash
681+
char const* p = key.data();
682+
char const* e = key.data() + key.size();
683+
char last = '\0';
684+
if (p == e || *p != '/') {
685+
// key must start with '/'
686+
absoluteKey.push_back('/');
687+
last = '/';
688+
}
689+
while (p < e) {
690+
char current = *p;
691+
if (current != '/' || last != '/') {
692+
// avoid repeated forward slashes
693+
absoluteKey.push_back(current);
694+
last = current;
695+
}
696+
++p;
697+
}
696698

697-
for (const auto& atom : VPackObjectIterator(transaction)) {
698-
std::string key(atom.key.copyString());
699-
keys.push_back(key);
700-
key = std::regex_replace(key, reg, "/");
701-
abskeys.push_back(((key[0] == '/') ? key : std::string("/") + key));
702-
idx.push_back(counter++);
703-
}
699+
TRI_ASSERT(!absoluteKey.empty());
700+
TRI_ASSERT(absoluteKey[0] == '/');
701+
TRI_ASSERT(absoluteKey.find("//") == std::string::npos);
704702

705-
sort(idx.begin(), idx.end(),
706-
[&abskeys](size_t i1, size_t i2) { return abskeys[i1] < abskeys[i2]; });
703+
idx.emplace_back(counter++, it.value());
707704

708-
_storeLock.assertLockedByCurrentThread();
705+
it.next();
706+
}
707+
708+
std::sort(idx.begin(), idx.end(),
709+
[&abskeys](std::pair<size_t, VPackSlice> const& i1, std::pair<size_t, VPackSlice> const& i2) noexcept {
710+
return abskeys[i1.first] < abskeys[i2.first];
711+
});
709712

710713
for (const auto& i : idx) {
711-
std::string const& key = keys.at(i);
712-
Slice value = transaction.get(key);
714+
Slice value = i.second;
713715

714716
if (value.isObject() && value.hasKey("op")) {
715-
if (value.get("op").isEqualString("delete") ||
716-
value.get("op").isEqualString("replace") ||
717-
value.get("op").isEqualString("erase")) {
718-
if (!_node.has(abskeys.at(i))) {
717+
Slice const op = value.get("op");
718+
719+
if (op.isEqualString("delete") ||
720+
op.isEqualString("replace") ||
721+
op.isEqualString("erase")) {
722+
if (!_node.has(abskeys.at(i.first))) {
719723
continue;
720724
}
721725
}
722-
auto uri = Node::normalize(abskeys.at(i));
723-
if (value.get("op").isEqualString("observe")) {
726+
auto uri = Node::normalize(abskeys.at(i.first));
727+
if (op.isEqualString("observe")) {
724728
bool found = false;
725-
if (value.hasKey("url") && value.get("url").isString()) {
729+
if (value.get("url").isString()) {
726730
auto url = value.get("url").copyString();
727731
auto ret = _observerTable.equal_range(url);
728732
for (auto it = ret.first; it != ret.second; ++it) {
@@ -736,8 +740,8 @@ bool Store::applies(arangodb::velocypack::Slice const& transaction) {
736740
_observedTable.emplace(std::pair<std::string, std::string>(uri, url));
737741
}
738742
}
739-
} else if (value.get("op").isEqualString("unobserve")) {
740-
if (value.hasKey("url") && value.get("url").isString()) {
743+
} else if (op.isEqualString("unobserve")) {
744+
if (value.get("url").isString()) {
741745
auto url = value.get("url").copyString();
742746
auto ret = _observerTable.equal_range(url);
743747
for (auto it = ret.first; it != ret.second; ++it) {
@@ -755,10 +759,10 @@ bool Store::applies(arangodb::velocypack::Slice const& transaction) {
755759
}
756760
}
757761
} else {
758-
_node.hasAsWritableNode(abskeys.at(i)).first.applieOp(value);
762+
_node.hasAsWritableNode(abskeys.at(i.first)).first.applieOp(value);
759763
}
760764
} else {
761-
_node.hasAsWritableNode(abskeys.at(i)).first.applies(value);
765+
_node.hasAsWritableNode(abskeys.at(i.first)).first.applies(value);
762766
}
763767
}
764768

@@ -884,3 +888,42 @@ void Store::removeTTL(std::string const& uri) {
884888
}
885889
}
886890
}
891+
892+
/// @brief Split strings by forward slashes, omitting empty strings
893+
std::vector<std::string> Store::split(std::string const& str) {
894+
std::vector<std::string> result;
895+
896+
char const* p = str.data();
897+
char const* e = str.data() + str.size();
898+
899+
// strip leading forward slashes
900+
while (p != e && *p == '/') {
901+
++p;
902+
}
903+
904+
// strip trailing forward slashes
905+
while (p != e && *(e - 1) == '/') {
906+
--e;
907+
}
908+
909+
char const* start = nullptr;
910+
while (p != e) {
911+
if (*p == '/') {
912+
if (start != nullptr) {
913+
// had already found something
914+
result.emplace_back(start, p - start);
915+
start = nullptr;
916+
}
917+
} else {
918+
if (start == nullptr) {
919+
start = p;
920+
}
921+
}
922+
++p;
923+
}
924+
if (start != nullptr) {
925+
result.emplace_back(start, p - start);
926+
}
927+
928+
return result;
929+
}

arangod/Agency/Store.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,10 @@ class Store {
148148
std::unordered_multimap<std::string, std::string>& observedTable();
149149
std::unordered_multimap<std::string, std::string> const& observedTable() const;
150150

151+
/// @brief Split strings by forward slashes, omitting empty strings
152+
/// this function is only public so that it can be test by unit tests
153+
static std::vector<std::string> split(std::string const& str);
154+
151155
private:
152156
/// @brief Check precondition
153157
check_ret_t check(arangodb::velocypack::Slice const&, CheckMode = FIRST_FAIL) const;

arangod/Aql/BlocksWithClients.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,6 @@ namespace transaction {
4747
class Methods;
4848
}
4949

50-
struct ClusterCommResult;
51-
5250
namespace aql {
5351
class AqlItemBlock;
5452
struct Collection;

0 commit comments

Comments
 (0)
0