summaryrefslogtreecommitdiffstats
path: root/sca-cpp/trunk/components/cache
diff options
context:
space:
mode:
Diffstat (limited to 'sca-cpp/trunk/components/cache')
-rw-r--r--sca-cpp/trunk/components/cache/Makefile.am2
-rw-r--r--sca-cpp/trunk/components/cache/cache.composite2
-rw-r--r--sca-cpp/trunk/components/cache/client-test.cpp83
-rw-r--r--sca-cpp/trunk/components/cache/datacache.cpp12
-rw-r--r--sca-cpp/trunk/components/cache/memcache-test.cpp26
-rw-r--r--sca-cpp/trunk/components/cache/memcache.cpp51
-rw-r--r--sca-cpp/trunk/components/cache/memcache.hpp78
-rw-r--r--sca-cpp/trunk/components/cache/memocache.cpp2
-rw-r--r--sca-cpp/trunk/components/cache/partitioner.cpp97
-rw-r--r--sca-cpp/trunk/components/cache/select-test.scm2
10 files changed, 184 insertions, 171 deletions
diff --git a/sca-cpp/trunk/components/cache/Makefile.am b/sca-cpp/trunk/components/cache/Makefile.am
index 0240a32bb4..3704a7a3ce 100644
--- a/sca-cpp/trunk/components/cache/Makefile.am
+++ b/sca-cpp/trunk/components/cache/Makefile.am
@@ -50,7 +50,7 @@ memcache_test_SOURCES = memcache-test.cpp
memcache_test_LDFLAGS = -lxml2
client_test_SOURCES = client-test.cpp
-client_test_LDFLAGS = -lxml2 -lcurl -lmozjs
+client_test_LDFLAGS = -lxml2 -lcurl -ljansson
dist_noinst_SCRIPTS = memcached-test memcached-ssl-test server-test
noinst_PROGRAMS = memcache-test client-test
diff --git a/sca-cpp/trunk/components/cache/cache.composite b/sca-cpp/trunk/components/cache/cache.composite
index a85f909db9..99fdd8ffc0 100644
--- a/sca-cpp/trunk/components/cache/cache.composite
+++ b/sca-cpp/trunk/components/cache/cache.composite
@@ -81,7 +81,7 @@
<service name="selector">
<binding.http uri="selector"/>
</service>
- </component>
+ </component>
<component name="partition1">
<implementation.scheme script="partition1-test.scm"/>
diff --git a/sca-cpp/trunk/components/cache/client-test.cpp b/sca-cpp/trunk/components/cache/client-test.cpp
index 63d1691f8b..5e9be6c14a 100644
--- a/sca-cpp/trunk/components/cache/client-test.cpp
+++ b/sca-cpp/trunk/components/cache/client-test.cpp
@@ -42,15 +42,15 @@ const string memocacheuri("http://localhost:8090/memocache");
const string partition1uri("http://localhost:8090/partitioner/a");
const string partition2uri("http://localhost:8090/partitioner/b");
-bool testCache(const string& uri) {
- http::CURLSession cs("", "", "", "", 0);
-
- const list<value> i = list<value>() + "content" + (list<value>() + "item"
- + (list<value>() + "name" + string("Apple"))
- + (list<value>() + "price" + string("$2.99")));
- const list<value> a = list<value>() + (list<value>() + "entry"
- + (list<value>() + "title" + string("item"))
- + (list<value>() + "id" + string("cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b"))
+const bool testCache(const string& uri) {
+ const http::CURLSession cs("", "", "", "", 0);
+
+ const list<value> i = nilListValue + "content" + (nilListValue + "item"
+ + (nilListValue + "name" + string("Apple"))
+ + (nilListValue + "price" + string("$2.99")));
+ const list<value> a = nilListValue + (nilListValue + "entry"
+ + (nilListValue + "title" + string("item"))
+ + (nilListValue + "id" + string("cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b"))
+ i);
const failable<value> id = http::post(a, uri, cs);
@@ -63,18 +63,18 @@ bool testCache(const string& uri) {
assert(content(val) == a);
}
- const list<value> j = list<value>() + "content" + (list<value>() + "item"
- + (list<value>() + "name" + string("Apple"))
- + (list<value>() + "price" + string("$3.55")));
- const list<value> b = list<value>() + (list<value>() + "entry"
- + (list<value>() + "title" + string("item"))
- + (list<value>() + "id" + string("cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b"))
+ const list<value> j = nilListValue + "content" + (nilListValue + "item"
+ + (nilListValue + "name" + string("Apple"))
+ + (nilListValue + "price" + string("$3.55")));
+ const list<value> b = nilListValue + (nilListValue + "entry"
+ + (nilListValue + "title" + string("item"))
+ + (nilListValue + "id" + string("cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b"))
+ j);
{
const failable<value> r = http::put(b, uri + p, cs);
assert(hasContent(r));
- assert(content(r) == value(true));
+ assert(content(r) == trueValue);
}
{
const failable<value> val = http::get(uri + p, cs);
@@ -84,7 +84,7 @@ bool testCache(const string& uri) {
{
const failable<value> r = http::del(uri + p, cs);
assert(hasContent(r));
- assert(content(r) == value(true));
+ assert(content(r) == trueValue);
}
{
const failable<value> val = http::get(uri + p, cs);
@@ -94,16 +94,16 @@ bool testCache(const string& uri) {
return true;
}
-bool testMemcache() {
+const bool testMemcache() {
return testCache(memcacheuri);
}
-bool testDatacache() {
+const bool testDatacache() {
return testCache(datacacheuri);
}
-bool testMemocache() {
- http::CURLSession cs("", "", "", "", 0);
+const bool testMemocache() {
+ const http::CURLSession cs("", "", "", "", 0);
const failable<value> res = http::evalExpr(mklist<value>(string("add"), 33, 22), memocacheuri, cs);
assert(hasContent(res));
@@ -116,8 +116,8 @@ bool testMemocache() {
return true;
}
-bool testPartitioner() {
- http::CURLSession cs("", "", "", "", 0);
+const bool testPartitioner() {
+ const http::CURLSession cs("", "", "", "", 0);
const failable<value> res1 = http::get(partition1uri, cs);
assert(hasContent(res1));
@@ -130,35 +130,26 @@ bool testPartitioner() {
return true;
}
-struct getLoop {
- const string path;
- const value entry;
- http::CURLSession& cs;
- getLoop(const string& path, const value& entry, http::CURLSession& cs) : path(path), entry(entry), cs(cs) {
- }
- const bool operator()() const {
- const failable<value> val = http::get(memcacheuri + path, cs);
- assert(hasContent(val));
- assert(content(val) == entry);
- return true;
- }
-};
-
-bool testGetPerf() {
- const list<value> i = list<value>() + "content" + (list<value>() + "item"
- + (list<value>() + "name" + string("Apple"))
- + (list<value>() + "price" + string("$4.55")));
- const list<value> a = list<value>() + (list<value>() + "entry"
- + (list<value>() + "title" + string("item"))
- + (list<value>() + "id" + string("cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b"))
+const bool testGetPerf() {
+ const list<value> i = nilListValue + "content" + (nilListValue + "item"
+ + (nilListValue + "name" + string("Apple"))
+ + (nilListValue + "price" + string("$4.55")));
+ const list<value> a = nilListValue + (nilListValue + "entry"
+ + (nilListValue + "title" + string("item"))
+ + (nilListValue + "id" + string("cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b"))
+ i);
- http::CURLSession cs("", "", "", "", 0);
+ const http::CURLSession cs("", "", "", "", 0);
const failable<value> id = http::post(a, memcacheuri, cs);
assert(hasContent(id));
const string p = path(content(id));
- const lambda<bool()> gl = getLoop(p, a, cs);
+ const blambda gl = [p, a, cs]() -> const bool {
+ const failable<value> val = http::get(memcacheuri + p, cs);
+ assert(hasContent(val));
+ assert(content(val) == a);
+ return true;
+ };
cout << "Cache get test " << time(gl, 5, 200) << " ms" << endl;
return true;
diff --git a/sca-cpp/trunk/components/cache/datacache.cpp b/sca-cpp/trunk/components/cache/datacache.cpp
index c259ec33c6..975ca43dce 100644
--- a/sca-cpp/trunk/components/cache/datacache.cpp
+++ b/sca-cpp/trunk/components/cache/datacache.cpp
@@ -44,7 +44,7 @@ namespace datacache {
/**
* Get an item from the cache.
*/
-const failable<value> get(const value& key, const lambda<value(const list<value>&)>& rcache1, const lambda<value(const list<value>&)>& wcache1, const lambda<value(const list<value>&)>& rcache2, unused const lambda<value(const list<value>&)>& wcache2) {
+const failable<value> get(const value& key, const lvvlambda& rcache1, const lvvlambda& wcache1, const lvvlambda& rcache2, unused const lvvlambda& wcache2) {
// Lookup level1 cache
const value val1 = rcache1(mklist<value>("get", key));
@@ -68,7 +68,7 @@ const failable<value> get(const value& key, const lambda<value(const list<value>
/**
* Post an item to the cache.
*/
-const failable<value> post(const value& key, const value& val, unused const lambda<value(const list<value>&)>& rcache1, const lambda<value(const list<value>&)>& wcache1, unused const lambda<value(const list<value>&)>& rcache2, const lambda<value(const list<value>&)>& wcache2) {
+const failable<value> post(const value& key, const value& val, unused const lvvlambda& rcache1, const lvvlambda& wcache1, unused const lvvlambda& rcache2, const lvvlambda& wcache2) {
const value id = append<value>(key, mklist(mkuuid()));
// Update level1 cache
@@ -83,7 +83,7 @@ const failable<value> post(const value& key, const value& val, unused const lamb
/**
* Put an item into the cache.
*/
-const failable<value> put(const value& key, const value& val, unused const lambda<value(const list<value>&)>& rcache1, const lambda<value(const list<value>&)>& wcache1, unused const lambda<value(const list<value>&)>& rcache2, const lambda<value(const list<value>&)>& wcache2) {
+const failable<value> put(const value& key, const value& val, unused const lvvlambda& rcache1, const lvvlambda& wcache1, unused const lvvlambda& rcache2, const lvvlambda& wcache2) {
// Update level1 cache
wcache1(mklist<value>("put", key, val));
@@ -91,13 +91,13 @@ const failable<value> put(const value& key, const value& val, unused const lambd
// Update level2 cache
wcache2(mklist<value>("put", key, val));
- return value(true);
+ return trueValue;
}
/**
* Delete an item from the cache.
*/
-const failable<value> del(const value& key, unused const lambda<value(const list<value>&)>& rcache1, const lambda<value(const list<value>&)>& wcache1, unused const lambda<value(const list<value>&)>& rcache2, const lambda<value(const list<value>&)>& wcache2) {
+const failable<value> del(const value& key, unused const lvvlambda& rcache1, const lvvlambda& wcache1, unused const lvvlambda& rcache2, const lvvlambda& wcache2) {
// Delete from level1 cache
wcache1(mklist<value>("delete", key));
@@ -105,7 +105,7 @@ const failable<value> del(const value& key, unused const lambda<value(const list
// Delete from level2 cache
wcache2(mklist<value>("delete", key));
- return value(true);
+ return trueValue;
}
}
diff --git a/sca-cpp/trunk/components/cache/memcache-test.cpp b/sca-cpp/trunk/components/cache/memcache-test.cpp
index 85fc339f1a..6c6adb0541 100644
--- a/sca-cpp/trunk/components/cache/memcache-test.cpp
+++ b/sca-cpp/trunk/components/cache/memcache-test.cpp
@@ -33,7 +33,7 @@ namespace tuscany {
namespace memcache {
bool testMemCached() {
- MemCached ch(mklist<string>("localhost:11211", "localhost:11212", "localhost:11213"));
+ const MemCached ch(mklist<string>("localhost:11211", "localhost:11212", "localhost:11213"));
const value k = mklist<value>("a");
assert(hasContent(post(k, string("AAA"), ch)));
@@ -46,24 +46,16 @@ bool testMemCached() {
return true;
}
-struct getLoop {
- const value k;
- MemCached& ch;
- getLoop(const value& k, MemCached& ch) : k(k), ch(ch) {
- }
- const bool operator()() const {
- gc_scoped_pool p;
- assert(get(k, ch) == value(string("CCC")));
- return true;
- }
-};
-
-bool testGetPerf() {
+const bool testGetPerf() {
const value k = mklist<value>("c");
- MemCached ch(mklist<string>("localhost:11211", "localhost:11212", "localhost:11213"));
+ const MemCached ch(mklist<string>("localhost:11211", "localhost:11212", "localhost:11213"));
assert(hasContent(post(k, string("CCC"), ch)));
- const lambda<bool()> gl = getLoop(k, ch);
+ const blambda gl = [k, ch]() -> const bool {
+ const gc_scoped_pool p;
+ assert(get(k, ch) == value(string("CCC")));
+ return true;
+ };
cout << "Memcached get test " << time(gl, 5, 200) << " ms" << endl;
return true;
}
@@ -72,7 +64,7 @@ bool testGetPerf() {
}
int main() {
- tuscany::gc_scoped_pool p;
+ const tuscany::gc_scoped_pool p;
tuscany::cout << "Testing..." << tuscany::endl;
tuscany::memcache::testMemCached();
diff --git a/sca-cpp/trunk/components/cache/memcache.cpp b/sca-cpp/trunk/components/cache/memcache.cpp
index 738a6ddd5a..2e4597efd3 100644
--- a/sca-cpp/trunk/components/cache/memcache.cpp
+++ b/sca-cpp/trunk/components/cache/memcache.cpp
@@ -37,14 +37,14 @@ namespace cache {
/**
* Get an item from the cache.
*/
-const failable<value> get(const list<value>& params, memcache::MemCached& ch) {
+const failable<value> get(const list<value>& params, const memcache::MemCached& ch) {
return memcache::get(car(params), ch);
}
/**
* Post an item to the cache.
*/
-const failable<value> post(const list<value>& params, memcache::MemCached& ch) {
+const failable<value> post(const list<value>& params, const memcache::MemCached& ch) {
const value id = append<value>(car(params), mklist(mkuuid()));
const failable<bool> val = memcache::post(id, cadr(params), ch);
if (!hasContent(val))
@@ -55,7 +55,7 @@ const failable<value> post(const list<value>& params, memcache::MemCached& ch) {
/**
* Put an item into the cache.
*/
-const failable<value> put(const list<value>& params, memcache::MemCached& ch) {
+const failable<value> put(const list<value>& params, const memcache::MemCached& ch) {
const failable<bool> val = memcache::put(car(params), cadr(params), ch);
if (!hasContent(val))
return mkfailure<value>(val);
@@ -65,7 +65,7 @@ const failable<value> put(const list<value>& params, memcache::MemCached& ch) {
/**
* Delete an item from the cache.
*/
-const failable<value> del(const list<value>& params, memcache::MemCached& ch) {
+const failable<value> del(const list<value>& params, const memcache::MemCached& ch) {
const failable<bool> val = memcache::del(car(params), ch);
if (!hasContent(val))
return mkfailure<value>(val);
@@ -73,37 +73,12 @@ const failable<value> del(const list<value>& params, memcache::MemCached& ch) {
}
/**
- * Component implementation lambda function.
- */
-class applyCache {
-public:
- applyCache(memcache::MemCached& ch) : ch(ch) {
- }
-
- const value operator()(const list<value>& params) const {
- const value func(car(params));
- if (func == "get")
- return get(cdr(params), ch);
- if (func == "post")
- return post(cdr(params), ch);
- if (func == "put")
- return put(cdr(params), ch);
- if (func == "delete")
- return del(cdr(params), ch);
- return mkfailure<value>();
- }
-
-private:
- memcache::MemCached& ch;
-};
-
-/**
* Convert a list of properties to a list of server addresses.
*/
const list<string> servers(const list<value>& params) {
if (isNil(params))
return list<string>();
- const value s = ((lambda<value(const list<value>&)>)car(params))(list<value>());
+ const value s = ((lvvlambda)car(params))(nilListValue);
return cons<string>(s, servers(cdr(params)));
}
@@ -112,10 +87,22 @@ const list<string> servers(const list<value>& params) {
*/
const failable<value> start(const list<value>& params) {
// Connect to memcached
- memcache::MemCached& ch = *(new (gc_new<memcache::MemCached>()) memcache::MemCached(servers(params)));
+ const memcache::MemCached& ch = *(new (gc_new<memcache::MemCached>()) memcache::MemCached(servers(params)));
// Return the component implementation lambda function
- return value(lambda<value(const list<value>&)>(applyCache(ch)));
+ const lvvlambda applyCache = [ch](const list<value>& params) -> const value {
+ const value func(car(params));
+ if (func == "get")
+ return get(cdr(params), ch);
+ if (func == "post")
+ return post(cdr(params), ch);
+ if (func == "put")
+ return put(cdr(params), ch);
+ if (func == "delete")
+ return del(cdr(params), ch);
+ return mkfailure<value>();
+ };
+ return value(applyCache);
}
}
diff --git a/sca-cpp/trunk/components/cache/memcache.hpp b/sca-cpp/trunk/components/cache/memcache.hpp
index f18405b2ec..00ee9c6291 100644
--- a/sca-cpp/trunk/components/cache/memcache.hpp
+++ b/sca-cpp/trunk/components/cache/memcache.hpp
@@ -48,43 +48,28 @@ namespace memcache {
*/
class MemCached {
public:
- MemCached() : owner(false) {
+ MemCached() : owner(false), mc(NULL) {
}
- MemCached(const string host, const int port) : p(), owner(true) {
- debug(host, "memcache::memcached::host");
- debug(port, "memcache::memcached::port");
- apr_memcache_create(pool(p), 1, 0, &mc);
- addServer(host, port);
+ MemCached(const string& host, const int port) : p(), owner(true), mc(mkmc(host, port)) {
}
- MemCached(const list<string>& servers) : p(), owner(true) {
- debug(servers, "memcache::memcached::servers");
- apr_memcache_create(pool(p), (apr_uint16_t)length(servers), 0, &mc);
- addServers(servers);
+ MemCached(const list<string>& servers) : p(), owner(true), mc(mkmc(servers)) {
}
MemCached(const MemCached& c) : p(c.p), owner(false), mc(c.mc) {
debug("memcache::memcached::copy");
}
- const MemCached& operator=(const MemCached& c) {
- debug("memcache::memcached::operator=");
- if(this == &c)
- return *this;
- p = c.p;
- owner = false;
- mc = c.mc;
- return *this;
- }
+ MemCached& operator=(const MemCached& c) = delete;
~MemCached() {
}
private:
- gc_child_pool p;
- bool owner;
- apr_memcache_t* mc;
+ const gc_child_pool p;
+ const bool owner;
+ apr_memcache_t* const mc;
friend const failable<bool> post(const value& key, const value& val, const MemCached& cache);
friend const failable<bool> put(const value& key, const value& val, const MemCached& cache);
@@ -94,7 +79,7 @@ private:
/**
* Add servers to the memcached context.
*/
- const failable<bool> addServer(const string& host, const int port) {
+ const failable<bool> addServer(apr_memcache_t* const m, const string& host, const int port) {
apr_memcache_server_t *server;
const apr_status_t sc = apr_memcache_server_create(pool(p), c_str(host), (apr_port_t)port, 1, 1, 1, 600, &server);
if (sc != APR_SUCCESS) {
@@ -102,27 +87,48 @@ private:
os << "Couldn't connect to memcached server: " << host << ":" << port;
return mkfailure<bool>(str(os));
}
- const apr_status_t as = apr_memcache_add_server(mc, server);
+ const apr_status_t as = apr_memcache_add_server(m, server);
if (as != APR_SUCCESS)
return mkfailure<bool>("Couldn't add memcached server");
return true;
}
- const failable<bool> addServers(const list<string>& servers) {
+ const failable<bool> addServers(apr_memcache_t* const m, const list<string>& servers) {
if (isNil(servers))
return true;
const list<string> toks = tokenize(":", car(servers));
- const failable<bool> r = addServer(car(toks), isNil(cdr(toks))? 11211 : atoi(c_str(cadr(toks))));
+ const failable<bool> r = addServer(m, car(toks), isNil(cdr(toks))? 11211 : atoi(c_str(cadr(toks))));
if (!hasContent(r))
return r;
- return addServers(cdr(servers));
+ return addServers(m, cdr(servers));
+ }
+
+ /**
+ * Create memcached handle.
+ */
+ apr_memcache_t* const mkmc(const string& host, const int port) {
+ debug(host, "memcache::memcached::host");
+ debug(port, "memcache::memcached::port");
+ apr_memcache_t* m;
+ apr_memcache_create(pool(p), 1, 0, &m);
+ addServer(m, host, port);
+ return m;
}
+
+ apr_memcache_t* const mkmc(const list<string>& servers) {
+ debug(servers, "memcache::memcached::servers");
+ apr_memcache_t* m;
+ apr_memcache_create(pool(p), (apr_uint16_t)length(servers), 0, &m);
+ addServers(m, servers);
+ return m;
+ }
+
};
/**
* Replace spaces by tabs (as spaces are not allowed in memcached keys).
*/
-const char* nospaces(const char* s) {
+const char* const nospaces(const char* const s) {
char* c = const_cast<char*>(s);
for (; *c; c++)
if (*c == ' ')
@@ -137,8 +143,8 @@ const failable<bool> post(const value& key, const value& val, const MemCached& c
debug(key, "memcache::post::key");
debug(val, "memcache::post::value");
- const string ks(scheme::writeValue(key));
- const string vs(scheme::writeValue(val));
+ const string ks(write(content(scheme::writeValue(key))));
+ const string vs(write(content(scheme::writeValue(val))));
const apr_status_t rc = apr_memcache_add(cache.mc, nospaces(c_str(ks)), const_cast<char*>(c_str(vs)), length(vs), 0, 27);
if (rc != APR_SUCCESS) {
ostringstream os;
@@ -157,8 +163,8 @@ const failable<bool> put(const value& key, const value& val, const MemCached& ca
debug(key, "memcache::put::key");
debug(val, "memcache::put::value");
- const string ks(scheme::writeValue(key));
- const string vs(scheme::writeValue(val));
+ const string ks(write(content(scheme::writeValue(key))));
+ const string vs(write(content(scheme::writeValue(val))));
const apr_status_t rc = apr_memcache_set(cache.mc, nospaces(c_str(ks)), const_cast<char*>(c_str(vs)), length(vs), 0, 27);
if (rc != APR_SUCCESS) {
ostringstream os;
@@ -176,17 +182,17 @@ const failable<bool> put(const value& key, const value& val, const MemCached& ca
const failable<value> get(const value& key, const MemCached& cache) {
debug(key, "memcache::get::key");
- const string ks(scheme::writeValue(key));
+ const string ks(write(content(scheme::writeValue(key))));
char *data;
apr_size_t size;
- gc_local_pool lp;
+ const gc_local_pool lp;
const apr_status_t rc = apr_memcache_getp(cache.mc, pool(lp), nospaces(c_str(ks)), &data, &size, NULL);
if (rc != APR_SUCCESS) {
ostringstream os;
os << "Couldn't get memcached entry: " << key;
return mkfailure<value>(str(os), 404, false);
}
- const value val(scheme::readValue(string(data, size)));
+ const value val(content(scheme::readValue(string(data, size))));
debug(val, "memcache::get::result");
return val;
@@ -198,7 +204,7 @@ const failable<value> get(const value& key, const MemCached& cache) {
const failable<bool> del(const value& key, const MemCached& cache) {
debug(key, "memcache::delete::key");
- const string ks(scheme::writeValue(key));
+ const string ks(write(content(scheme::writeValue(key))));
const apr_status_t rc = apr_memcache_delete(cache.mc, nospaces(c_str(ks)), 0);
if (rc != APR_SUCCESS) {
ostringstream os;
diff --git a/sca-cpp/trunk/components/cache/memocache.cpp b/sca-cpp/trunk/components/cache/memocache.cpp
index e7e52cdc59..5539ccee2f 100644
--- a/sca-cpp/trunk/components/cache/memocache.cpp
+++ b/sca-cpp/trunk/components/cache/memocache.cpp
@@ -42,7 +42,7 @@ namespace memocache {
/**
* Memoize the value of a function application in a cache.
*/
-const failable<value> memoize(const list<value>& params, const lambda<value(const list<value>&)>& relay, const lambda<value(const list<value>&)>& cache) {
+const failable<value> memoize(const list<value>& params, const lvvlambda& relay, const lvvlambda& cache) {
debug(params, "memocache::memoize::params");
// Lookup memoized value from cache
diff --git a/sca-cpp/trunk/components/cache/partitioner.cpp b/sca-cpp/trunk/components/cache/partitioner.cpp
index e3f04ba112..a38c053358 100644
--- a/sca-cpp/trunk/components/cache/partitioner.cpp
+++ b/sca-cpp/trunk/components/cache/partitioner.cpp
@@ -22,7 +22,7 @@
/**
* A partitioner component implementation which forwards data access requests to a
* dynamically selected data store component. The selection is externalized, performed
- * by a selector component, responsible for selecting the target data store given the
+ * by a selector component, responsible for selecting the target data stores given the
* data access request key and a list of references to available data store components.
* This pattern can be used for sharding or load balancing for example.
*/
@@ -38,54 +38,89 @@ namespace tuscany {
namespace partitioner {
/**
- * Return the target partition for a key.
+ * Return a list of target partitions for a key.
*/
-const failable<lambda<value(const list<value>&)> > partition(const value& key, const lambda<value(const list<value>&)>& selector, const list<value>& partitions) {
+const failable<list<value> > partition(const value& key, const lvvlambda& selector, const list<value>& partitions) {
- // Call the selector component to convert the given key to a partition number
+ // Call the selector component to convert the given key to a list of partitions
const value p = selector(mklist<value>("get", key, partitions));
if (isNil(p)) {
ostringstream os;
- os << "Couldn't get partition number: " << key;
- return mkfailure<lambda<value(const list<value>&)> >(str(os), -1, false);
+ os << "Couldn't get partition: " << key;
+ return mkfailure<list<value> >(str(os), -1, false);
}
- return (const lambda<value(const list<value>&)>)p;
+ return (list<value>)p;
+}
+
+
+/**
+ * Get lists of items from a list of partitions.
+ */
+const failable<list<value> > getlist(const value& key, const list<value>& partitions) {
+ if (isNil(partitions))
+ return nilListValue;
+
+ const lvvlambda l = car(partitions);
+ const value val = l(mklist<value>("get", key));
+ if (isNil(val))
+ return getlist(key, cdr(partitions));
+ if (!isList(val)) {
+ ostringstream os;
+ os << "Couldn't get list of entries from partition: " << key;
+ return mkfailure<list<value> >(str(os), 500, false);
+ }
+
+ const failable<list<value> > cdrval = getlist(key, cdr(partitions));
+ if (!hasContent(cdrval))
+ return cdrval;
+
+ return append<value>((list<value>)val, content(cdrval));
}
/**
* Get an item from a partition.
*/
-const failable<value> get(const value& key, const lambda<value(const list<value>&)>& selector, const list<value>& partitions) {
+const failable<value> get(const value& key, const lvvlambda& selector, const list<value>& partitions) {
// Select partition
- const failable<lambda<value(const list<value>&)> > p = partition(key, selector, partitions);
- if (!hasContent(p))
- return mkfailure<value>(p);
-
- // Get from selected partition
- const value val = content(p)(mklist<value>("get", key));
- if (isNil(val)) {
- ostringstream os;
- os << "Couldn't get entry from partition: " << key;
- return mkfailure<value>(str(os), 404, false);
+ const failable<list<value> > fp = partition(key, selector, partitions);
+ if (!hasContent(fp))
+ return mkfailure<value>(fp);
+ const list<value> p = content(fp);
+
+ // Get a single item from the selected partition
+ if (length(p) == 1) {
+ const lvvlambda l = car(p);
+ const value val = l(mklist<value>("get", key));
+ if (isNil(val)) {
+ ostringstream os;
+ os << "Couldn't get entry from partition: " << key;
+ return mkfailure<value>(str(os), 404, false);
+ }
+ return val;
}
- return val;
+ // Get list of items from the list of selected partitions
+ const failable<list<value> > val = getlist(key, p);
+ if (!hasContent(val))
+ return mkfailure<value>(val);
+ return (value)content(val);
}
/**
* Post an item to a partition.
*/
-const failable<value> post(const value& key, const value& val, const lambda<value(const list<value>&)>& selector, const list<value>& partitions) {
+const failable<value> post(const value& key, const value& val, const lvvlambda& selector, const list<value>& partitions) {
const value id = append<value>(key, mklist(mkuuid()));
// Select partition
- const failable<lambda<value(const list<value>&)> > p = partition(id, selector, partitions);
+ const failable<list<value> > p = partition(id, selector, partitions);
if (!hasContent(p))
return mkfailure<value>(p);
// Put into select partition
- content(p)(mklist<value>("put", id, val));
+ const lvvlambda l = car(content(p));
+ l(mklist<value>("post", id, val));
return id;
}
@@ -93,33 +128,35 @@ const failable<value> post(const value& key, const value& val, const lambda<valu
/**
* Put an item into a partition.
*/
-const failable<value> put(const value& key, const value& val, const lambda<value(const list<value>&)>& selector, const list<value>& partitions) {
+const failable<value> put(const value& key, const value& val, const lvvlambda& selector, const list<value>& partitions) {
// Select partition
- const failable<lambda<value(const list<value>&)> > p = partition(key, selector, partitions);
+ const failable<list<value> > p = partition(key, selector, partitions);
if (!hasContent(p))
return mkfailure<value>(p);
// Put into selected partition
- content(p)(mklist<value>("put", key, val));
+ const lvvlambda l = car(content(p));
+ l(mklist<value>("put", key, val));
- return value(true);
+ return trueValue;
}
/**
* Delete an item from a partition.
*/
-const failable<value> del(const value& key, const lambda<value(const list<value>&)>& selector, const list<value>& partitions) {
+const failable<value> del(const value& key, const lvvlambda& selector, const list<value>& partitions) {
// Select partition
- const failable<lambda<value(const list<value>&)> > p = partition(key, selector, partitions);
+ const failable<list<value> > p = partition(key, selector, partitions);
if (!hasContent(p))
return mkfailure<value>(p);
// Delete from selected partition
- content(p)(mklist<value>("delete", key));
+ const lvvlambda l = car(content(p));
+ l(mklist<value>("delete", key));
- return value(true);
+ return trueValue;
}
}
diff --git a/sca-cpp/trunk/components/cache/select-test.scm b/sca-cpp/trunk/components/cache/select-test.scm
index 9baa82a5da..f788a6104a 100644
--- a/sca-cpp/trunk/components/cache/select-test.scm
+++ b/sca-cpp/trunk/components/cache/select-test.scm
@@ -17,5 +17,5 @@
; Partition selector test case
-(define (get key partitions) (if (= (car key) "a") (car partitions) (cadr partitions)))
+(define (get key partitions) (if (= (car key) "a") (list (car partitions)) (list (cadr partitions))))