[Liblas-commits] libpc: converted lru cache to a PointData cache,
with the needed...
liblas-commits at liblas.org
liblas-commits at liblas.org
Thu Mar 10 21:17:35 EST 2011
details: http://hg.liblas.orglibpc/rev/5a15af27864a
changeset: 206:5a15af27864a
user: Michael P. Gerlek <mpg at flaxen.com>
date: Thu Mar 10 18:17:28 2011 -0800
description:
converted lru cache to a PointData cache, with the needed semantics
diffstat:
include/libpc/LruCache.hpp | 64 +++++++++------
test/unit/LruCacheTest.cpp | 187 ++++++++++++++------------------------------
2 files changed, 98 insertions(+), 153 deletions(-)
diffs (truncated from 337 to 300 lines):
diff -r 862128245ebc -r 5a15af27864a include/libpc/LruCache.hpp
--- a/include/libpc/LruCache.hpp Thu Mar 10 17:42:55 2011 -0800
+++ b/include/libpc/LruCache.hpp Thu Mar 10 18:17:28 2011 -0800
@@ -36,12 +36,10 @@
namespace libpc
{
-// Class providing fixed-size (by number of records)
-// LRU-replacement cache of a function with signature
-// V f(K)
+class PointData;
-template <typename K,typename V> class LruCache
+class LruCache
{
public:
@@ -50,44 +48,60 @@
// Bimap with key access on left view, key access
// history on right view, and associated value.
typedef boost::bimaps::bimap<
- boost::bimaps::set_of<K>,
+ boost::bimaps::set_of<boost::uint32_t>,
boost::bimaps::list_of<dummy_type>,
- boost::bimaps::with_info<V>
+ boost::bimaps::with_info<PointData*>
> cache_type;
// Constuctor specifies the cached function and
// the maximum number of records to be stored.
- LruCache(
- const boost::function<V(const K&)>& f,
- size_t c
- )
- :_fn(f)
- ,_capacity(c)
+ LruCache(size_t c)
+ :_capacity(c)
{
assert(_capacity!=0);
}
- // Obtain value of the cached function for k
- V operator()(const K& k)
+ ~LruCache()
{
+ for (cache_type::left_iterator it =_cache.left.begin(); it != _cache.left.end(); ++it)
+ {
+ PointData* data = it->info;
+ delete data;
+ }
+ return;
+ }
+ PointData* lookup(boost::uint32_t k)
+ {
// Attempt to find existing record
- const typename cache_type::left_iterator it
- =_cache.left.find(k);
+ const cache_type::left_iterator it =_cache.left.find(k);
if (it==_cache.left.end())
{
-
// We don't have it:
- // Evaluate function and create new record
- const V v=_fn(k);
- insert(k,v);
- return v;
-
+ return NULL;
}
else
{
+ // We do have it:
+ return it->info;
+ }
+ }
+ // Obtain value of the cached function for k
+ PointData* insert(boost::uint32_t k, PointData* v)
+ {
+ // Attempt to find existing record
+ const cache_type::left_iterator it =_cache.left.find(k);
+
+ if (it==_cache.left.end())
+ {
+ // We don't have it: insert it
+ insertx(k,v);
+ return v;
+ }
+ else
+ {
// We do have it:
// Update the access record view.
_cache.right.relocate(
@@ -116,9 +130,8 @@
private:
- void insert(const K& k,const V& v)
+ void insertx(boost::uint32_t k, PointData* v)
{
-
assert(_cache.size()<=_capacity);
// If necessary, make space
@@ -130,13 +143,12 @@
// Create a new record from the key, a dummy and the value
_cache.insert(
- typename cache_type::value_type(
+ cache_type::value_type(
k,0,v
)
);
}
- const boost::function<V(const K&)> _fn;
const size_t _capacity;
cache_type _cache;
diff -r 862128245ebc -r 5a15af27864a test/unit/LruCacheTest.cpp
--- a/test/unit/LruCacheTest.cpp Thu Mar 10 17:42:55 2011 -0800
+++ b/test/unit/LruCacheTest.cpp Thu Mar 10 18:17:28 2011 -0800
@@ -19,6 +19,7 @@
#include <boost/test/unit_test.hpp>
+#include "libpc/PointData.hpp"
#include "libpc/LruCache.hpp"
using namespace libpc;
@@ -38,143 +39,75 @@
BOOST_AUTO_TEST_CASE(test1)
{
- count_evaluations=0;
-
- LruCache<std::string,std::string> lru(fn,5);
-
- // Some initial accesses to prime state
- BOOST_CHECK_EQUAL(lru("first"),"tsrif");
- BOOST_CHECK_EQUAL(lru("second"),"dnoces");
- BOOST_CHECK_EQUAL(lru("third"),"driht");
- BOOST_CHECK_EQUAL(lru("fourth"),"htruof");
- BOOST_CHECK_EQUAL(lru("fifth"),"htfif");
- BOOST_CHECK_EQUAL(count_evaluations,5);
- BOOST_CHECK_EQUAL(lru("sixth"),"htxis");
- BOOST_CHECK_EQUAL(count_evaluations,6);
+ Schema schema;
+ Dimension d1(Dimension::Field_X, Dimension::Uint32);
+ schema.addDimension(d1);
+ SchemaLayout layout(schema);
- // This should be retrieved from cache
- BOOST_CHECK_EQUAL(lru("second"),"dnoces");
- BOOST_CHECK_EQUAL(count_evaluations,6);
+ PointData* item0 = new PointData(layout, 10);
+ PointData* item00 = new PointData(layout, 10);
+ PointData* item1 = new PointData(layout, 10);
+ PointData* item11 = new PointData(layout, 10);
+ PointData* item2 = new PointData(layout, 10);
+ PointData* item22 = new PointData(layout, 10);
- // This will have been evicted
- BOOST_CHECK_EQUAL(lru("first"),"tsrif");
- BOOST_CHECK_EQUAL(count_evaluations,7);
-
- // Cache contents by access time
- // (most recent to least recent)
- // should now be:
- // first,second,sixth,fifth,fourth
- {
- std::vector<std::string> expected;
- expected.push_back("first");
- expected.push_back("second");
- expected.push_back("sixth");
- expected.push_back("fifth");
- expected.push_back("fourth");
- std::vector<std::string> actual;
- lru.get_keys(std::back_inserter(actual));
- BOOST_CHECK(actual==expected);
- }
-
- // So check fourth is retrieved
- BOOST_CHECK_EQUAL(lru("fourth"),"htruof");
- BOOST_CHECK_EQUAL(count_evaluations,7);
-
- // That will have moved up "fourth" to the head
- // so this will evict fifth
- BOOST_CHECK_EQUAL(lru("seventh"),"htneves");
- BOOST_CHECK_EQUAL(count_evaluations,8);
-
- // Check fifth was evicted as expected
- BOOST_CHECK_EQUAL(lru("fifth"),"htfif");
- BOOST_CHECK_EQUAL(count_evaluations,9);
-
- return;
-}
-
-
-class MyItem
-{
-public:
- MyItem(int index, double data) : m_index(index), m_data(data) {}
- MyItem(const MyItem& other)
+ // write the data into the buffer
+ for (int i=0; i<10; i++)
{
- m_index = other.m_index;
- m_data = other.m_data;
+ item0->setField(i, 0, i);
+ item00->setField(i, 0, i);
+ item1->setField(i, 0, i+10);
+ item11->setField(i, 0, i+10);
+ item2->setField(i, 0, i+20);
+ item22->setField(i, 0, i+20);
}
- MyItem& operator=(MyItem const& rhs)
- {
- if (&rhs != this)
- {
- m_index = rhs.m_index;
- m_data = rhs.m_data;
- }
- return *this;
+ LruCache lru(2);
+
+ // bunch of insertions/lookups
+ lru.insert(0,item0);
+ lru.insert(0,item0);
+ lru.insert(10,item1);
+ lru.insert(10,item1);
+ lru.insert(10,item0);
+ lru.insert(0,item0);
+ lru.insert(20,item2);
+ lru.insert(20,item2);
+ lru.insert(0,item0);
+
+ BOOST_CHECK(lru.lookup(0) == item0);
+ BOOST_CHECK(lru.lookup(10) == NULL);
+ BOOST_CHECK(lru.lookup(20) == item2);
+
+ {
+ std::vector<boost::uint32_t> actual;
+ lru.get_keys(std::back_inserter(actual));
+ BOOST_CHECK(actual.size() == 2);
+ BOOST_CHECK(actual[0] == 0);
+ BOOST_CHECK(actual[1] == 20);
}
- bool operator==(const MyItem& other) const
- {
- if (m_index == other.m_index) return true;
- return false;
+ lru.insert(0,item00);
+ lru.insert(20,item22);
+
+ {
+ std::vector<boost::uint32_t> actual;
+ lru.get_keys(std::back_inserter(actual));
+ BOOST_CHECK(actual.size() == 2);
+ BOOST_CHECK(actual[0] == 20);
+ BOOST_CHECK(actual[1] == 0);
}
- int m_index;
- double m_data;
-};
+ BOOST_CHECK(lru.lookup(0) == item0);
+ BOOST_CHECK(lru.lookup(10) == NULL);
+ BOOST_CHECK(lru.lookup(20) == item2);
-// Dummy function we want to cache
-int cache_func(MyItem* item)
-{
- ++count_evaluations;
- return item->m_index;
-}
-
-BOOST_AUTO_TEST_CASE(test2)
-{
- MyItem* item1 = new MyItem(1,11);
- MyItem* item11 = new MyItem(1,11);
- MyItem* item2 = new MyItem(2,22);
- MyItem* item3 = new MyItem(3,33);
- MyItem* item33 = new MyItem(3,33);
-
- count_evaluations = 0;
-
- LruCache<MyItem*,int> lru(cache_func,2);
-
- // bunch of insertions/lookups
- lru(item1);
- lru(item1);
- lru(item2);
- lru(item2);
More information about the Liblas-commits
mailing list