[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