1
0
Fork 0

Merge branch 'sharding' of ssh://github.com/triAGENS/ArangoDB into sharding

This commit is contained in:
Max Neunhoeffer 2014-01-03 15:11:48 +01:00
commit f0cb458e9d
4 changed files with 217 additions and 2 deletions

View File

@ -204,6 +204,79 @@ std::string AgencyCommResult::errorDetails () const {
/// @brief recursively flatten the JSON response into a map
////////////////////////////////////////////////////////////////////////////////
bool AgencyCommResult::processJsonNode (TRI_json_t const* node,
std::map<std::string, bool>& out,
std::string const& stripKeyPrefix) const {
if (! TRI_IsArrayJson(node)) {
return true;
}
// get "key" attribute
TRI_json_t const* key = TRI_LookupArrayJson(node, "key");
if (! TRI_IsStringJson(key)) {
return false;
}
// make sure we don't strip more bytes than the key is long
const size_t offset = AgencyComm::_globalPrefix.size() + stripKeyPrefix.size();
const size_t length = key->_value._string.length - 1;
std::string prefix;
if (offset >= length) {
prefix = "";
}
else {
prefix = std::string(key->_value._string.data + offset,
key->_value._string.length - 1 - offset);
}
// get "dir" attribute
TRI_json_t const* dir = TRI_LookupArrayJson(node, "dir");
bool isDir = (TRI_IsBooleanJson(dir) && dir->_value._boolean);
if (isDir) {
out.insert(std::make_pair<std::string, bool>(prefix, true));
// is a directory, so there may be a "nodes" attribute
TRI_json_t const* nodes = TRI_LookupArrayJson(node, "nodes");
if (! TRI_IsListJson(nodes)) {
// if directory is empty...
return true;
}
const size_t n = TRI_LengthVector(&nodes->_value._objects);
for (size_t i = 0; i < n; ++i) {
if (! processJsonNode((TRI_json_t const*) TRI_AtVector(&nodes->_value._objects, i),
out,
stripKeyPrefix)) {
return false;
}
}
}
else {
// not a directory
// get "value" attribute
TRI_json_t const* value = TRI_LookupArrayJson(node, "value");
if (TRI_IsStringJson(value)) {
if (! prefix.empty()) {
// otherwise return value
out.insert(std::make_pair<std::string, bool>(prefix, false));
}
}
}
return true;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief recursively flatten the JSON response into a map
////////////////////////////////////////////////////////////////////////////////
bool AgencyCommResult::processJsonNode (TRI_json_t const* node,
std::map<std::string, std::string>& out,
std::string const& stripKeyPrefix,
@ -273,11 +346,13 @@ bool AgencyCommResult::processJsonNode (TRI_json_t const* node,
}
// convert the number to an integer
out[prefix] = triagens::basics::StringUtils::itoa((uint64_t) modifiedIndex->_value._number);
out.insert(std::make_pair<std::string, std::string>(prefix,
triagens::basics::StringUtils::itoa((uint64_t) modifiedIndex->_value._number)));
}
else {
// otherwise return value
out[prefix] = std::string(value->_value._string.data, value->_value._string.length - 1);
out.insert(std::make_pair<std::string, std::string>(prefix,
std::string(value->_value._string.data, value->_value._string.length - 1)));
}
}
@ -291,6 +366,30 @@ bool AgencyCommResult::processJsonNode (TRI_json_t const* node,
/// @brief turn a result into a map
////////////////////////////////////////////////////////////////////////////////
bool AgencyCommResult::flattenJson (std::map<std::string, bool>& out,
std::string const& stripKeyPrefix) const {
TRI_json_t* json = TRI_JsonString(TRI_UNKNOWN_MEM_ZONE, _body.c_str());
if (! TRI_IsArrayJson(json)) {
if (json != 0) {
TRI_FreeJson(TRI_UNKNOWN_MEM_ZONE, json);
}
return false;
}
// get "node" attribute
TRI_json_t const* node = TRI_LookupArrayJson(json, "node");
const bool result = processJsonNode(node, out, stripKeyPrefix);
TRI_FreeJson(TRI_UNKNOWN_MEM_ZONE, json);
return result;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief turn a result into a map
////////////////////////////////////////////////////////////////////////////////
bool AgencyCommResult::flattenJson (std::map<std::string, std::string>& out,
std::string const& stripKeyPrefix,
bool returnIndex) const {

View File

@ -189,6 +189,14 @@ namespace triagens {
return _body;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief recursively flatten the JSON response into a map
////////////////////////////////////////////////////////////////////////////////
bool processJsonNode (struct TRI_json_s const*,
std::map<std::string, bool>&,
std::string const&) const;
////////////////////////////////////////////////////////////////////////////////
/// @brief recursively flatten the JSON response into a map
////////////////////////////////////////////////////////////////////////////////
@ -198,6 +206,13 @@ namespace triagens {
std::string const&,
bool) const;
////////////////////////////////////////////////////////////////////////////////
/// @brief turn a result into a map
////////////////////////////////////////////////////////////////////////////////
bool flattenJson (std::map<std::string, bool>&,
std::string const&) const;
////////////////////////////////////////////////////////////////////////////////
/// @brief turn a result into a map
////////////////////////////////////////////////////////////////////////////////

View File

@ -231,6 +231,49 @@ static v8::Handle<v8::Value> JS_GetAgency (v8::Arguments const& argv) {
return scope.Close(l);
}
////////////////////////////////////////////////////////////////////////////////
/// @brief lists a directory from the agency
////////////////////////////////////////////////////////////////////////////////
static v8::Handle<v8::Value> JS_ListAgency (v8::Arguments const& argv) {
v8::HandleScope scope;
if (argv.Length() < 1) {
TRI_V8_EXCEPTION_USAGE(scope, "list(<key>, <recursive>)");
}
const std::string key = TRI_ObjectToString(argv[0]);
bool recursive = false;
if (argv.Length() > 1) {
recursive = TRI_ObjectToBoolean(argv[1]);
}
AgencyComm comm;
AgencyCommResult result = comm.getValues(key, recursive);
if (! result.successful()) {
return scope.Close(v8::ThrowException(CreateAgencyException(result)));
}
v8::Handle<v8::Object> l = v8::Object::New();
// return just the value for each key
std::map<std::string, bool> out;
result.flattenJson(out, "");
std::map<std::string, bool>::const_iterator it = out.begin();
while (it != out.end()) {
const std::string key = (*it).first;
const bool isDirectory = (*it).second;
l->Set(v8::String::New(key.c_str(), key.size()), v8::Boolean::New(isDirectory));
++it;
}
return scope.Close(l);
}
////////////////////////////////////////////////////////////////////////////////
/// @brief acquires a read-lock in the agency
////////////////////////////////////////////////////////////////////////////////
@ -658,6 +701,7 @@ void TRI_InitV8Cluster (v8::Handle<v8::Context> context) {
TRI_AddMethodVocbase(rt, "createDirectory", JS_CreateDirectoryAgency);
TRI_AddMethodVocbase(rt, "get", JS_GetAgency);
TRI_AddMethodVocbase(rt, "isEnabled", JS_IsEnabledAgency);
TRI_AddMethodVocbase(rt, "list", JS_ListAgency);
TRI_AddMethodVocbase(rt, "lockRead", JS_LockReadAgency);
TRI_AddMethodVocbase(rt, "lockWrite", JS_LockWriteAgency);
TRI_AddMethodVocbase(rt, "remove", JS_RemoveAgency);

View File

@ -68,6 +68,63 @@ function AgencySuite () {
assertMatch(/^etcd/, agency.version());
},
////////////////////////////////////////////////////////////////////////////////
/// @brief test list
////////////////////////////////////////////////////////////////////////////////
testList : function () {
assertTrue(agency.createDirectory("UnitTestsAgency/foo"));
assertTrue(agency.set("UnitTestsAgency/foo/1", "foo1"));
assertTrue(agency.set("UnitTestsAgency/foo/2", "foo2"));
assertTrue(agency.set("UnitTestsAgency/foo/3", "foo3"));
assertTrue(agency.createDirectory("UnitTestsAgency/foo/bam"));
assertTrue(agency.createDirectory("UnitTestsAgency/foo/bar"));
assertTrue(agency.set("UnitTestsAgency/foo/bar/1", "bar1"));
assertTrue(agency.set("UnitTestsAgency/foo/bar/2", "bar2"));
assertTrue(agency.createDirectory("UnitTestsAgency/foo/bar/baz"));
assertTrue(agency.set("UnitTestsAgency/foo/bar/baz/1", "baz1"));
assertTrue(agency.createDirectory("UnitTestsAgency/foo/bar/baz/bam"));
var values = agency.list("UnitTestsAgency/foo");
assertEqual({
"UnitTestsAgency/foo" : true,
"UnitTestsAgency/foo/1" : false,
"UnitTestsAgency/foo/2" : false,
"UnitTestsAgency/foo/3" : false,
"UnitTestsAgency/foo/bam" : true,
"UnitTestsAgency/foo/bar" : true
}, values);
values = agency.list("UnitTestsAgency/foo", true);
assertEqual({
"UnitTestsAgency/foo" : true,
"UnitTestsAgency/foo/1" : false,
"UnitTestsAgency/foo/2" : false,
"UnitTestsAgency/foo/3" : false,
"UnitTestsAgency/foo/bam" : true,
"UnitTestsAgency/foo/bar" : true,
"UnitTestsAgency/foo/bar/1" : false,
"UnitTestsAgency/foo/bar/2" : false,
"UnitTestsAgency/foo/bar/baz" : true,
"UnitTestsAgency/foo/bar/baz/1" : false,
"UnitTestsAgency/foo/bar/baz/bam" : true
}, values);
// insert a new directory (above the others, sort order is important)
assertTrue(agency.createDirectory("UnitTestsAgency/foo/abc"));
values = agency.list("UnitTestsAgency/foo");
assertEqual({
"UnitTestsAgency/foo" : true,
"UnitTestsAgency/foo/1" : false,
"UnitTestsAgency/foo/2" : false,
"UnitTestsAgency/foo/3" : false,
"UnitTestsAgency/foo/abc" : true,
"UnitTestsAgency/foo/bam" : true,
"UnitTestsAgency/foo/bar" : true
}, values);
},
////////////////////////////////////////////////////////////////////////////////
/// @brief test lockRead
////////////////////////////////////////////////////////////////////////////////