From 9558dae78cdbcf1909ab7649d2a02ab010c0d35c Mon Sep 17 00:00:00 2001 From: jsdelfino Date: Wed, 20 Oct 2010 04:59:43 +0000 Subject: Renamed frontcache to datacache and add a memo cache that memoizes function applications. git-svn-id: http://svn.us.apache.org/repos/asf/tuscany@1024519 13f79535-47bb-0310-9956-ffa450edef68 --- sca-cpp/trunk/components/cache/Makefile.am | 16 ++- sca-cpp/trunk/components/cache/adder-test.scm | 20 ++++ sca-cpp/trunk/components/cache/cache.composite | 68 +++++++++++ sca-cpp/trunk/components/cache/client-test.cpp | 24 +++- sca-cpp/trunk/components/cache/datacache.cpp | 125 +++++++++++++++++++++ sca-cpp/trunk/components/cache/frontcache.cpp | 125 --------------------- sca-cpp/trunk/components/cache/memcache.composite | 52 --------- sca-cpp/trunk/components/cache/memocache.cpp | 77 +++++++++++++ sca-cpp/trunk/components/cache/server-test | 2 +- .../samples/store-cluster/shared/shared.composite | 2 +- sca-cpp/trunk/samples/store-sql/store.composite | 2 +- 11 files changed, 323 insertions(+), 190 deletions(-) create mode 100644 sca-cpp/trunk/components/cache/adder-test.scm create mode 100644 sca-cpp/trunk/components/cache/cache.composite create mode 100644 sca-cpp/trunk/components/cache/datacache.cpp delete mode 100644 sca-cpp/trunk/components/cache/frontcache.cpp delete mode 100644 sca-cpp/trunk/components/cache/memcache.composite create mode 100644 sca-cpp/trunk/components/cache/memocache.cpp diff --git a/sca-cpp/trunk/components/cache/Makefile.am b/sca-cpp/trunk/components/cache/Makefile.am index 03e63f12ed..e6181ace05 100644 --- a/sca-cpp/trunk/components/cache/Makefile.am +++ b/sca-cpp/trunk/components/cache/Makefile.am @@ -25,18 +25,22 @@ comp_DATA = memcached.prefix memcached.prefix: $(top_builddir)/config.status echo ${MEMCACHED_PREFIX} >memcached.prefix -EXTRA_DIST = memcache.composite +EXTRA_DIST = cache.composite -comp_LTLIBRARIES = libmemcache.la libfrontcache.la -noinst_DATA = libmemcache.so libfrontcache.so +comp_LTLIBRARIES = libmemcache.la libdatacache.la libmemocache.la +noinst_DATA = libmemcache.so libdatacache.so libmemocache.so libmemcache_la_SOURCES = memcache.cpp libmemcache.so: ln -s .libs/libmemcache.so -libfrontcache_la_SOURCES = frontcache.cpp -libfrontcache.so: - ln -s .libs/libfrontcache.so +libdatacache_la_SOURCES = datacache.cpp +libdatacache.so: + ln -s .libs/libdatacache.so + +libmemocache_la_SOURCES = memocache.cpp +libmemocache.so: + ln -s .libs/libmemocache.so memcache_test_SOURCES = memcache-test.cpp memcache_test_LDFLAGS = -lxml2 diff --git a/sca-cpp/trunk/components/cache/adder-test.scm b/sca-cpp/trunk/components/cache/adder-test.scm new file mode 100644 index 0000000000..ccd5bc555f --- /dev/null +++ b/sca-cpp/trunk/components/cache/adder-test.scm @@ -0,0 +1,20 @@ +; Licensed to the Apache Software Foundation (ASF) under one +; or more contributor license agreements. See the NOTICE file +; distributed with this work for additional information +; regarding copyright ownership. The ASF licenses this file +; to you under the Apache License, Version 2.0 (the +; "License"); you may not use this file except in compliance +; with the License. You may obtain a copy of the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, +; software distributed under the License is distributed on an +; "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +; KIND, either express or implied. See the License for the +; specific language governing permissions and limitations +; under the License. + +; Logger test case + +(define (add a b) (+ a b)) diff --git a/sca-cpp/trunk/components/cache/cache.composite b/sca-cpp/trunk/components/cache/cache.composite new file mode 100644 index 0000000000..1f3302614d --- /dev/null +++ b/sca-cpp/trunk/components/cache/cache.composite @@ -0,0 +1,68 @@ + + + + + + + + + + localhost,localhost:11212,localhost:11213 + + + + + + + + localhost:11411,localhost:11412,localhost:11413 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/sca-cpp/trunk/components/cache/client-test.cpp b/sca-cpp/trunk/components/cache/client-test.cpp index 4fb4cfe4e1..fce911a302 100644 --- a/sca-cpp/trunk/components/cache/client-test.cpp +++ b/sca-cpp/trunk/components/cache/client-test.cpp @@ -37,7 +37,8 @@ namespace tuscany { namespace cache { const string memcacheuri("http://localhost:8090/memcache"); -const string frontcacheuri("http://localhost:8090/frontcache"); +const string datacacheuri("http://localhost:8090/datacache"); +const string memocacheuri("http://localhost:8090/memocache"); bool testCache(const string& uri) { http::CURLSession cs("", "", ""); @@ -89,8 +90,22 @@ bool testMemcache() { return testCache(memcacheuri); } -bool testFrontcache() { - return testCache(frontcacheuri); +bool testDatacache() { + return testCache(datacacheuri); +} + +bool testMemocache() { + http::CURLSession cs("", "", ""); + + const failable res = http::evalExpr(mklist(string("add"), 33, 22), memocacheuri, cs); + assert(hasContent(res)); + assert((int)content(res) == 55); + + const failable res2 = http::evalExpr(mklist(string("add"), 33, 22), memocacheuri, cs); + assert(hasContent(res2)); + assert((int)content(res2) == 55); + + return true; } struct getLoop { @@ -131,7 +146,8 @@ int main() { tuscany::cout << "Testing..." << tuscany::endl; tuscany::cache::testMemcache(); - tuscany::cache::testFrontcache(); + tuscany::cache::testDatacache(); + tuscany::cache::testMemocache(); tuscany::cache::testGetPerf(); tuscany::cout << "OK" << tuscany::endl; diff --git a/sca-cpp/trunk/components/cache/datacache.cpp b/sca-cpp/trunk/components/cache/datacache.cpp new file mode 100644 index 0000000000..e1cfdbfa57 --- /dev/null +++ b/sca-cpp/trunk/components/cache/datacache.cpp @@ -0,0 +1,125 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +/* $Rev$ $Date$ */ + +/** + * A data cache component implementation which coordinates access to two + * levels of backend read/write caches or stores. Each cache or store is + * accessed through two references: a writer reference and a reader reference. + * + * This is useful if your level2 store is made of a master and slave + * replicated databases, you can then wire the writer reference to the master + * database and the reader reference to one your slave databases (assuming + * that the updates eventually get replicated to the slave database, in the + * meantime the updates will be retrieved from the level1 cache). + */ + +#include "string.hpp" +#include "function.hpp" +#include "list.hpp" +#include "value.hpp" +#include "monad.hpp" + +namespace tuscany { +namespace datacache { + +/** + * Get an item from the cache. + */ +const failable get(const value& key, const lambda&)> rcache1, const lambda&)> wcache1, const lambda&)> rcache2, unused const lambda&)> wcache2) { + + // Lookup level1 cache + const value val1 = rcache1(mklist("get", key)); + if (!isNil(val1)) + return val1; + + // Lookup level2 cache + const value val2 = rcache2(mklist("get", key)); + if (isNil(val2)) + return mkfailure("Couldn't get cache entry"); + + // Update level1 cache + wcache1(mklist("put", key, val2)); + + return val2; +} + +/** + * Post an item to the cache. + */ +const failable post(const value& key, const value& val, unused const lambda&)> rcache1, const lambda&)> wcache1, unused const lambda&)> rcache2, const lambda&)> wcache2) { + const value id = append(key, mklist(mkuuid())); + + // Update level1 cache + wcache1(mklist("put", id, val)); + + // Update level2 cache + wcache2(mklist("put", id, val)); + + return id; +} + +/** + * Put an item into the cache. + */ +const failable put(const value& key, const value& val, unused const lambda&)> rcache1, const lambda&)> wcache1, unused const lambda&)> rcache2, const lambda&)> wcache2) { + + // Update level1 cache + wcache1(mklist("put", key, val)); + + // Update level2 cache + wcache2(mklist("put", key, val)); + + return value(true); +} + +/** + * Delete an item from the cache. + */ +const failable del(const value& key, unused const lambda&)> rcache1, const lambda&)> wcache1, unused const lambda&)> rcache2, const lambda&)> wcache2) { + + // Delete from level1 cache + wcache1(mklist("delete", key)); + + // Delete from level2 cache + wcache2(mklist("delete", key)); + + return value(true); +} + +} +} + +extern "C" { + +const tuscany::value apply(const tuscany::list& params) { + const tuscany::value func(car(params)); + if (func == "get") + return tuscany::datacache::get(cadr(params), caddr(params), cadddr(params), caddddr(params), cadddddr(params)); + if (func == "post") + 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 == "delete") + return tuscany::datacache::del(cadr(params), caddr(params), cadddr(params), caddddr(params), cadddddr(params)); + return tuscany::mkfailure(); +} + +} diff --git a/sca-cpp/trunk/components/cache/frontcache.cpp b/sca-cpp/trunk/components/cache/frontcache.cpp deleted file mode 100644 index a9b18f0792..0000000000 --- a/sca-cpp/trunk/components/cache/frontcache.cpp +++ /dev/null @@ -1,125 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -/* $Rev$ $Date$ */ - -/** - * A front cache component implementation which coordinates access to two - * levels of backend read/write caches or stores. Each cache or store is - * accessed through two references: a writer reference and a reader reference. - * - * This is useful if your level2 store is made of a master and slave - * replicated databases, you can then wire the writer reference to the master - * database and the reader reference to one your slave databases (assuming - * that the updates eventually get replicated to the slave database,in the - * meantime the updates will be retrieved from the level1 cache). - */ - -#include "string.hpp" -#include "function.hpp" -#include "list.hpp" -#include "value.hpp" -#include "monad.hpp" - -namespace tuscany { -namespace frontcache { - -/** - * Get an item from the cache. - */ -const failable get(const value& key, const lambda&)> rcache1, const lambda&)> wcache1, const lambda&)> rcache2, unused const lambda&)> wcache2) { - - // Lookup level1 cache - const value val1 = rcache1(mklist("get", key)); - if (!isNil(val1)) - return val1; - - // Lookup level2 cache - const value val2 = rcache2(mklist("get", key)); - if (isNil(val2)) - return mkfailure("Couldn't get cache entry"); - - // Update level1 cache - wcache1(mklist("put", key, val2)); - - return val2; -} - -/** - * Post an item to the cache. - */ -const failable post(const value& key, const value& val, unused const lambda&)> rcache1, const lambda&)> wcache1, unused const lambda&)> rcache2, const lambda&)> wcache2) { - const value id = append(key, mklist(mkuuid())); - - // Update level1 cache - wcache1(mklist("put", id, val)); - - // Update level2 cache - wcache2(mklist("put", id, val)); - - return id; -} - -/** - * Put an item into the cache. - */ -const failable put(const value& key, const value& val, unused const lambda&)> rcache1, const lambda&)> wcache1, unused const lambda&)> rcache2, const lambda&)> wcache2) { - - // Update level1 cache - wcache1(mklist("put", key, val)); - - // Update level2 cache - wcache2(mklist("put", key, val)); - - return value(true); -} - -/** - * Delete an item from the cache. - */ -const failable del(const value& key, unused const lambda&)> rcache1, const lambda&)> wcache1, unused const lambda&)> rcache2, const lambda&)> wcache2) { - - // Delete from level1 cache - wcache1(mklist("delete", key)); - - // Delete from level2 cache - wcache2(mklist("delete", key)); - - return value(true); -} - -} -} - -extern "C" { - -const tuscany::value apply(const tuscany::list& params) { - const tuscany::value func(car(params)); - if (func == "get") - return tuscany::frontcache::get(cadr(params), caddr(params), cadddr(params), caddddr(params), cadddddr(params)); - if (func == "post") - return tuscany::frontcache::post(cadr(params), caddr(params), cadddr(params), caddddr(params), cadddddr(params), caddddddr(params)); - if (func == "put") - return tuscany::frontcache::put(cadr(params), caddr(params), cadddr(params), caddddr(params), cadddddr(params), caddddddr(params)); - if (func == "delete") - return tuscany::frontcache::del(cadr(params), caddr(params), cadddr(params), caddddr(params), cadddddr(params)); - return tuscany::mkfailure(); -} - -} diff --git a/sca-cpp/trunk/components/cache/memcache.composite b/sca-cpp/trunk/components/cache/memcache.composite deleted file mode 100644 index 4d546db410..0000000000 --- a/sca-cpp/trunk/components/cache/memcache.composite +++ /dev/null @@ -1,52 +0,0 @@ - - - - - - - - - - localhost,localhost:11212,localhost:11213 - - - - - - - - localhost:11411,localhost:11412,localhost:11413 - - - - - - - - - - - - - - diff --git a/sca-cpp/trunk/components/cache/memocache.cpp b/sca-cpp/trunk/components/cache/memocache.cpp new file mode 100644 index 0000000000..2482c2202b --- /dev/null +++ b/sca-cpp/trunk/components/cache/memocache.cpp @@ -0,0 +1,77 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +/* $Rev$ $Date$ */ + +/** + * A cache component implementation which memoizes the value of function + * applications, keyed by the function arguments, in a key/value cache passed + * as a reference. + * + * This is useful if your functions are idempotent and applied many times to + * the same arguments. The results can then be retrieved quickly from the + * cache without actually applying the function. + */ + +#include "string.hpp" +#include "function.hpp" +#include "list.hpp" +#include "value.hpp" +#include "monad.hpp" + +namespace tuscany { +namespace memocache { + +/** + * Memoize the value of a function application in a cache. + */ +const failable memoize(const list& params, const lambda&)> relay, const lambda&)> cache) { + debug(params, "memocache::memoize::params"); + + // Lookup memoized value from cache + const value val = cache(mklist("get", params)); + if (!isNil(val)) { + debug(val, "memocache::memoize::cached"); + return val; + } + + // Apply the given function + const value res = relay(params); + debug(res, "memocache::memoize::res"); + + // Store the result value in the cache + cache(mklist("put", params, res)); + + return res; +} + +} +} + +extern "C" { + +const tuscany::value apply(const tuscany::list& params) { + const tuscany::value func(car(params)); + if (func == "start" || func == "stop") + return tuscany::mkfailure(); + const tuscany::list rev = tuscany::reverse(params); + return tuscany::memocache::memoize(tuscany::reverse(tuscany::cddr(rev)), tuscany::cadr(rev), tuscany::car(rev)); +} + +} diff --git a/sca-cpp/trunk/components/cache/server-test b/sca-cpp/trunk/components/cache/server-test index a93a7e73ac..6d14f789f5 100755 --- a/sca-cpp/trunk/components/cache/server-test +++ b/sca-cpp/trunk/components/cache/server-test @@ -23,7 +23,7 @@ ../../modules/server/scheme-conf tmp cat >>tmp/conf/httpd.conf < - + diff --git a/sca-cpp/trunk/samples/store-sql/store.composite b/sca-cpp/trunk/samples/store-sql/store.composite index 18a77c2802..a10740b5f9 100644 --- a/sca-cpp/trunk/samples/store-sql/store.composite +++ b/sca-cpp/trunk/samples/store-sql/store.composite @@ -60,7 +60,7 @@ - + -- cgit v1.2.3