diff options
Diffstat (limited to '')
-rw-r--r-- | sca-cpp/trunk/components/cache/client-test.cpp | 26 | ||||
-rw-r--r-- | sca-cpp/trunk/components/cache/datacache.cpp | 16 | ||||
-rw-r--r-- | sca-cpp/trunk/components/cache/memcache-test.cpp | 2 | ||||
-rw-r--r-- | sca-cpp/trunk/components/cache/memcache.cpp | 35 | ||||
-rw-r--r-- | sca-cpp/trunk/components/cache/memcache.hpp | 23 | ||||
-rw-r--r-- | sca-cpp/trunk/components/cache/partitioner.cpp | 19 |
6 files changed, 120 insertions, 1 deletions
diff --git a/sca-cpp/trunk/components/cache/client-test.cpp b/sca-cpp/trunk/components/cache/client-test.cpp index 5e9be6c14a..3c8a261f84 100644 --- a/sca-cpp/trunk/components/cache/client-test.cpp +++ b/sca-cpp/trunk/components/cache/client-test.cpp @@ -81,6 +81,32 @@ const bool testCache(const string& uri) { assert(hasContent(val)); assert(content(val) == b); } + + const list<value> k = nilListValue + "content" + (nilListValue + "item" + + (nilListValue + "name" + string("Apple")) + + (nilListValue + "price" + string("$3.99"))); + const list<value> c = nilListValue + (nilListValue + "entry" + + (nilListValue + "title" + string("item")) + + (nilListValue + "id" + string("cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b")) + + k); + + { + const list<value> s = nilListValue + "content" + + (nilListValue + "patch" + string("(define (patch id e) (tree-subst-assoc '(price) '(price \"$3.99\") e))")); + const list<value> ps = nilListValue + (nilListValue + "entry" + + (nilListValue + "title" + string("item")) + + (nilListValue + "id" + string("cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b")) + + s); + + const failable<value> r = http::patch(ps, uri + p, cs); + assert(hasContent(r)); + assert(content(r) == trueValue); + } + { + const failable<value> val = http::get(uri + p, cs); + assert(hasContent(val)); + assert(content(val) == c); + } { const failable<value> r = http::del(uri + p, cs); assert(hasContent(r)); diff --git a/sca-cpp/trunk/components/cache/datacache.cpp b/sca-cpp/trunk/components/cache/datacache.cpp index 975ca43dce..4fafd9e345 100644 --- a/sca-cpp/trunk/components/cache/datacache.cpp +++ b/sca-cpp/trunk/components/cache/datacache.cpp @@ -95,6 +95,20 @@ const failable<value> put(const value& key, const value& val, unused const lvvla } /** + * Patch an item in the cache. + */ +const failable<value> patch(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>("patch", key, val)); + + // Update level2 cache + wcache2(mklist<value>("patch", key, val)); + + return trueValue; +} + +/** * Delete an item from the cache. */ const failable<value> del(const value& key, unused const lvvlambda& rcache1, const lvvlambda& wcache1, unused const lvvlambda& rcache2, const lvvlambda& wcache2) { @@ -121,6 +135,8 @@ const tuscany::value apply(const tuscany::list<tuscany::value>& params) { return tuscany::datacache::post(cadr(params), caddr(params), cadddr(params), caddddr(params), cadddddr(params), caddddddr(params)); if (func == "put") return tuscany::datacache::put(cadr(params), caddr(params), cadddr(params), caddddr(params), cadddddr(params), caddddddr(params)); + if (func == "patch") + return tuscany::datacache::patch(cadr(params), caddr(params), cadddr(params), caddddr(params), cadddddr(params), caddddddr(params)); if (func == "delete") return tuscany::datacache::del(cadr(params), caddr(params), cadddr(params), caddddr(params), cadddddr(params)); return tuscany::mkfailure<tuscany::value>(); diff --git a/sca-cpp/trunk/components/cache/memcache-test.cpp b/sca-cpp/trunk/components/cache/memcache-test.cpp index 6c6adb0541..10eda45eae 100644 --- a/sca-cpp/trunk/components/cache/memcache-test.cpp +++ b/sca-cpp/trunk/components/cache/memcache-test.cpp @@ -40,6 +40,8 @@ bool testMemCached() { assert(get(k, ch) == value(string("AAA"))); assert(hasContent(put(k, string("aaa"), ch))); assert(get(k, ch) == value(string("aaa"))); + assert(hasContent(patch(k, string("bbb"), ch))); + assert(get(k, ch) == value(string("bbb"))); assert(hasContent(del(k, ch))); assert(!hasContent(get(k, ch))); diff --git a/sca-cpp/trunk/components/cache/memcache.cpp b/sca-cpp/trunk/components/cache/memcache.cpp index 2e4597efd3..e1a3c7e9af 100644 --- a/sca-cpp/trunk/components/cache/memcache.cpp +++ b/sca-cpp/trunk/components/cache/memcache.cpp @@ -63,6 +63,39 @@ const failable<value> put(const list<value>& params, const memcache::MemCached& } /** + * Patch an item in the cache. + */ +const failable<value> patch(const list<value>& params, const memcache::MemCached& ch) { + // Read patch + value p = assoc<value>("patch", assoc<value>("content", car<value>(cadr(params)))); + if (isNil(p)) + return mkfailure<value>("Couldn't read patch script"); + const string script = cadr<value>(p); + debug(script, "memcache::patch::script"); + istringstream is(script); + + // Get existing value from cache + const failable<value> ival = memcache::get(car(params), ch); + if (!hasContent(ival) && rcode(ival) != 404) + return mkfailure<value>(ival); + + // Apply patch + scheme::Env env = scheme::setupEnvironment(); + const value pval = scheme::evalScript(cons<value>("patch", scheme::quotedParameters(mklist<value>(car(params), hasContent(ival)? content(ival) : (value)list<value>()))), is, env); + if (isNil(pval)) { + ostringstream os; + os << "Couldn't patch memcached entry: " << car(params); + return mkfailure<value>(str(os), 404, false); + } + + // Push patched value to cache + const failable<bool> val = memcache::patch(car(params), pval, ch); + if (!hasContent(val)) + return mkfailure<value>(val); + return value(content(val)); +} + +/** * Delete an item from the cache. */ const failable<value> del(const list<value>& params, const memcache::MemCached& ch) { @@ -98,6 +131,8 @@ const failable<value> start(const list<value>& params) { return post(cdr(params), ch); if (func == "put") return put(cdr(params), ch); + if (func == "patch") + return patch(cdr(params), ch); if (func == "delete") return del(cdr(params), ch); return mkfailure<value>(); diff --git a/sca-cpp/trunk/components/cache/memcache.hpp b/sca-cpp/trunk/components/cache/memcache.hpp index 00ee9c6291..7962d1caa0 100644 --- a/sca-cpp/trunk/components/cache/memcache.hpp +++ b/sca-cpp/trunk/components/cache/memcache.hpp @@ -73,6 +73,7 @@ private: 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); + friend const failable<bool> patch(const value& key, const value& val, const MemCached& cache); friend const failable<value> get(const value& key, const MemCached& cache); friend const failable<bool> del(const value& key, const MemCached& cache); @@ -177,6 +178,26 @@ const failable<bool> put(const value& key, const value& val, const MemCached& ca } /** + * Patch an item in the cache. If the item doesn't exist it is added. + */ +const failable<bool> patch(const value& key, const value& val, const MemCached& cache) { + debug(key, "memcache::patch::key"); + debug(val, "memcache::patch::value"); + + 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; + os << "Couldn't set memcached entry: " << key; + return mkfailure<bool>(str(os)); + } + + debug(true, "memcache::patch::result"); + return true; +} + +/** * Get an item from the cache. */ const failable<value> get(const value& key, const MemCached& cache) { @@ -209,7 +230,7 @@ const failable<bool> del(const value& key, const MemCached& cache) { if (rc != APR_SUCCESS) { ostringstream os; os << "Couldn't delete memcached entry: " << key; - return mkfailure<bool>(str(os)); + return rc == APR_NOTFOUND? mkfailure<bool>(str(os), 404, false) : mkfailure<bool>(str(os)); } debug(true, "memcache::delete::result"); diff --git a/sca-cpp/trunk/components/cache/partitioner.cpp b/sca-cpp/trunk/components/cache/partitioner.cpp index a38c053358..8a56a7f932 100644 --- a/sca-cpp/trunk/components/cache/partitioner.cpp +++ b/sca-cpp/trunk/components/cache/partitioner.cpp @@ -143,6 +143,23 @@ const failable<value> put(const value& key, const value& val, const lvvlambda& s } /** + * Patch an item in a partition. + */ +const failable<value> patch(const value& key, const value& val, const lvvlambda& selector, const list<value>& partitions) { + + // Select partition + const failable<list<value> > p = partition(key, selector, partitions); + if (!hasContent(p)) + return mkfailure<value>(p); + + // Path item in selected partition + const lvvlambda l = car(content(p)); + l(mklist<value>("patch", key, val)); + + return trueValue; +} + +/** * Delete an item from a partition. */ const failable<value> del(const value& key, const lvvlambda& selector, const list<value>& partitions) { @@ -172,6 +189,8 @@ const tuscany::value apply(const tuscany::list<tuscany::value>& params) { return tuscany::partitioner::post(cadr(params), caddr(params), cadddr(params), cddddr(params)); if (func == "put") return tuscany::partitioner::put(cadr(params), caddr(params), cadddr(params), cddddr(params)); + if (func == "patch") + return tuscany::partitioner::patch(cadr(params), caddr(params), cadddr(params), cddddr(params)); if (func == "delete") return tuscany::partitioner::del(cadr(params), caddr(params), cdddr(params)); return tuscany::mkfailure<tuscany::value>(); |