diff --git a/Makefile b/Makefile
index 1ad4df5..30684bc 100644
--- a/Makefile
+++ b/Makefile
@@ -3,7 +3,9 @@
 PLATFORM=OS_LINUX
 PLATFORM_LDFLAGS= -lpthread -lrt -lsnappy -lgflags -lz -lbz2 -llz4 -lzstd
 
-CXXFLAGS = -Wall -Wno-reorder -I/usr/local/include -O2 -std=c++11 
+CXXFLAGS = -Wall -Wno-reorder -I/usr/local/include -g -std=c++11 
+
+ARFLAGS = ${EXTRA_ARFLAGS} rs
 
 ifneq ($(USE_RTTI), 1)
 	CXXFLAGS += -fno-rtti
@@ -12,11 +14,18 @@
 
 LIBOBJECTS = $(LIB_SOURCES:.cc=.o)
 
-collocatordb: collocatordb.cc
+testcdb: testcdb.cc collocatordb.h collocatordb.o Makefile
+	$(CXX) $(CXXFLAGS) -L. -L/usr/local/lib $@.cc -o$@ collocatordb.o -lrocksdb $(PLATFORM_LDFLAGS) $(PLATFORM_CXXFLAGS) $(EXEC_LDFLAGS)
+
+collocatordb: collocatordb.cc Makefile
 	$(CXX) $(CXXFLAGS) -L/usr/local/lib $@.cc -o$@ -lrocksdb $(PLATFORM_LDFLAGS) $(PLATFORM_CXXFLAGS) $(EXEC_LDFLAGS)
 
 libcollocatordb.a: $(LIBOBJECTS)
+	$(AM_V_AR)rm -f $@
 	$(AM_V_at)$(AR) $(ARFLAGS) $@ $(LIBOBJECTS)
 
+libcollocatordb.so.1: collocatordb.cc
+	$(CXX) $(CXXFLAGS) -c collocatordb.cc -Wl,-soname=libcollocatordb.so.1 -Wl,--version-script=collocatordb.exmap -shared -fPIC -o libcollocatordb.so.1
+
 .cc.o:
 	$(CXX) $(CXXFLAGS) -c $< -o$@ $(PLATFORM_CXXFLAGS)
diff --git a/collocatordb.cc b/collocatordb.cc
index 4eb6134..cfc5969 100644
--- a/collocatordb.cc
+++ b/collocatordb.cc
@@ -4,6 +4,8 @@
 //  (found in the LICENSE.Apache file in the root directory).
 //
 #include <typeinfo>
+#define EXPORT __attribute__((visibility("visible")))
+#define IMPORT
 #include <assert.h>
 #include <memory>
 #include <iostream>
@@ -23,270 +25,302 @@
 #define DIST(key) (int8_t)((uint64_t)((key >> 56) & 0xff))
 using namespace rocksdb;
 
-namespace {
+namespace rocksdb {
   size_t num_merge_operator_calls;
   void resetNumMergeOperatorCalls() { num_merge_operator_calls = 0; }
   
   size_t num_partial_merge_calls;
   void resetNumPartialMergeCalls() { num_partial_merge_calls = 0; }
-}
-
-inline void EncodeFixed64(char* buf, uint64_t value) {
-  if (! IS_BIG_ENDIAN) {
-    memcpy(buf, &value, sizeof(value));
-  } else {
-    buf[0] = value & 0xff;
-    buf[1] = (value >> 8) & 0xff;
-    buf[2] = (value >> 16) & 0xff;
-    buf[3] = (value >> 24) & 0xff;
-    buf[4] = (value >> 32) & 0xff;
-    buf[5] = (value >> 40) & 0xff;
-    buf[6] = (value >> 48) & 0xff;
-    buf[7] = (value >> 56) & 0xff;
-  }
-}
-
-inline uint32_t DecodeFixed32(const char* ptr) {
-  if (! IS_BIG_ENDIAN) {
-    // Load the raw bytes
-    uint32_t result;
-    memcpy(&result, ptr, sizeof(result));  // gcc optimizes this to a plain load
-    return result;
-  } else {
-    return ((static_cast<uint32_t>(static_cast<unsigned char>(ptr[0])))
-            | (static_cast<uint32_t>(static_cast<unsigned char>(ptr[1])) << 8)
-            | (static_cast<uint32_t>(static_cast<unsigned char>(ptr[2])) << 16)
-            | (static_cast<uint32_t>(static_cast<unsigned char>(ptr[3])) << 24));
-  }
-}
-
-inline uint64_t DecodeFixed64(const char* ptr) {
-  if (! IS_BIG_ENDIAN) {
-    // Load the raw bytes
-    uint64_t result;
-    memcpy(&result, ptr, sizeof(result));  // gcc optimizes this to a plain load
-    return result;
-  } else {
-    uint64_t lo = DecodeFixed32(ptr);
-    uint64_t hi = DecodeFixed32(ptr + 4);
-    return (hi << 32) | lo;
-  }
-}
 
 
-class CountMergeOperator : public AssociativeMergeOperator {
-public:
-  CountMergeOperator() {
-    mergeOperator_ = MergeOperators::CreateUInt64AddOperator();
+  inline void EncodeFixed64(char* buf, uint64_t value) {
+    if (! IS_BIG_ENDIAN) {
+      memcpy(buf, &value, sizeof(value));
+    } else {
+      buf[0] = value & 0xff;
+      buf[1] = (value >> 8) & 0xff;
+      buf[2] = (value >> 16) & 0xff;
+      buf[3] = (value >> 24) & 0xff;
+      buf[4] = (value >> 32) & 0xff;
+      buf[5] = (value >> 40) & 0xff;
+      buf[6] = (value >> 48) & 0xff;
+      buf[7] = (value >> 56) & 0xff;
+    }
   }
 
-  virtual bool Merge(const Slice& key,
-                     const Slice* existing_value,
-                     const Slice& value,
-                     std::string* new_value,
-                     Logger* logger) const override {
-    assert(new_value->empty());
-    ++num_merge_operator_calls;
-    if (existing_value == nullptr) {
-      new_value->assign(value.data(), value.size());
-      return true;
+  inline uint32_t DecodeFixed32(const char* ptr) {
+    if (! IS_BIG_ENDIAN) {
+      // Load the raw bytes
+      uint32_t result;
+      memcpy(&result, ptr, sizeof(result));  // gcc optimizes this to a plain load
+      return result;
+    } else {
+      return ((static_cast<uint32_t>(static_cast<unsigned char>(ptr[0])))
+              | (static_cast<uint32_t>(static_cast<unsigned char>(ptr[1])) << 8)
+              | (static_cast<uint32_t>(static_cast<unsigned char>(ptr[2])) << 16)
+              | (static_cast<uint32_t>(static_cast<unsigned char>(ptr[3])) << 24));
+    }
+  }
+
+  inline uint64_t DecodeFixed64(const char* ptr) {
+    if (! IS_BIG_ENDIAN) {
+      // Load the raw bytes
+      uint64_t result;
+      memcpy(&result, ptr, sizeof(result));  // gcc optimizes this to a plain load
+      return result;
+    } else {
+      uint64_t lo = DecodeFixed32(ptr);
+      uint64_t hi = DecodeFixed32(ptr + 4);
+      return (hi << 32) | lo;
+    }
+  }
+
+
+  class CountMergeOperator : public AssociativeMergeOperator {
+  public:
+    CountMergeOperator() {
+      mergeOperator_ = MergeOperators::CreateUInt64AddOperator();
     }
 
-    return mergeOperator_->PartialMerge(
-                                        key,
-                                        *existing_value,
-                                        value,
-                                        new_value,
-                                        logger);
-  }
+    virtual bool Merge(const Slice& key,
+                       const Slice* existing_value,
+                       const Slice& value,
+                       std::string* new_value,
+                       Logger* logger) const override {
+      assert(new_value->empty());
+      ++num_merge_operator_calls;
+      if (existing_value == nullptr) {
+        new_value->assign(value.data(), value.size());
+        return true;
+      }
 
-  virtual const char* Name() const override {
-    return "UInt64AddOperator";
-  }
+      return mergeOperator_->PartialMerge(
+                                          key,
+                                          *existing_value,
+                                          value,
+                                          new_value,
+                                          logger);
+    }
 
-private:
-  std::shared_ptr<MergeOperator> mergeOperator_;
-};
+    virtual const char* Name() const override {
+      return "UInt64AddOperator";
+    }
 
-namespace {
-}  // namespace
+  private:
+    std::shared_ptr<MergeOperator> mergeOperator_;
+  };
+    
 
-class CollocatorIterator : public Iterator {
-private:
-  char prefixc[sizeof(uint64_t)];
-  Iterator *base_iterator_;
+  class CollocatorIterator : public Iterator {
+  private:
+    char prefixc[sizeof(uint64_t)];
+    Iterator *base_iterator_;
+        
+        
+  public:
+    CollocatorIterator(Iterator* base_iterator)
+      : base_iterator_(base_iterator)
+    {}
+
+    ~CollocatorIterator();
+
+    void setPrefix(char *prefix) {
+      memcpy(prefixc, prefix, sizeof(uint64_t));
+    }
+
+    virtual void SeekToFirst() { base_iterator_->SeekToFirst(); }
+    virtual void SeekToLast() { base_iterator_->SeekToLast(); }
+    virtual void Seek(const rocksdb::Slice& s) { base_iterator_->Seek(s); }
+    virtual void Prev() { base_iterator_->Prev(); }
+    virtual void Next() { base_iterator_->Next(); }
+    virtual Slice key() const;
+    virtual Slice value() const;
+    virtual Status status() const;
+    virtual bool Valid() const;
+    bool isValid();
+    uint64_t intValue();
+    uint64_t intKey();
   
+  };
 
-public:
-  explicit CollocatorIterator(Iterator* base_iterator)
-    : base_iterator_(base_iterator)
-  {}
-
-  void setPrefix(char *prefix) {
-    memcpy(prefixc, prefix, sizeof(uint64_t));
-  }
-
-  virtual void SeekToFirst() { base_iterator_->SeekToFirst(); }
-  virtual void SeekToLast() { base_iterator_->SeekToLast(); }
-  virtual void Seek(const rocksdb::Slice& s) { base_iterator_->Seek(s); }
-  virtual void Prev() { base_iterator_->Prev(); }
-  virtual void Next() { base_iterator_->Next(); }
-  virtual Slice key() const { return base_iterator_->key(); }
-  virtual Slice value() const { return base_iterator_->value(); }
-  virtual Status status() const { return base_iterator_->status(); }
-  
-  virtual bool Valid() const override {
+  //  rocksdb::CollocatorIterator::CollocatorIterator(Iterator* base_iterator) {}
+    
+  bool rocksdb::CollocatorIterator::Valid() const {
     return base_iterator_->Valid() && key().starts_with(std::string(prefixc,3));
   }
-};
 
+  bool rocksdb::CollocatorIterator::isValid() {
+    return base_iterator_->Valid() && key().starts_with(std::string(prefixc,3));
+  }
 
-class Collocators {
-private:
-  WriteOptions merge_option_; // for merge
-  char _one[sizeof(uint64_t)];
-  Slice _one_slice;
+  uint64_t rocksdb::CollocatorIterator::intKey() {
+    return DecodeFixed64(base_iterator_->key().data());
+  }
   
-protected:
-  std::shared_ptr<DB> db_;
-
-  WriteOptions put_option_;
-  ReadOptions get_option_;
-  WriteOptions delete_option_;
-
-  uint64_t default_;
-
-  std::shared_ptr<DB> OpenDb(const std::string& dbname, const bool ttl = false,
-                             const size_t max_successive_merges = 0) {
-    DB* db;
-    Options options;
-    options.create_if_missing = true;
-    options.merge_operator = std::make_shared<CountMergeOperator>();
-    options.max_successive_merges = max_successive_merges;
-    Status s;
-    //  DestroyDB(dbname, Options());
-    s = DB::Open(options, dbname, &db);
-    if (!s.ok()) {
-      std::cerr << s.ToString() << std::endl;
-      assert(false);
-    }
-    return std::shared_ptr<DB>(db);
+  uint64_t rocksdb::CollocatorIterator::intValue() {
+    return DecodeFixed64(base_iterator_->value().data());
   }
 
-public:
- explicit Collocators(const std::string& db_name)
-   : put_option_(),
-     get_option_(),
-     delete_option_(),
-     merge_option_()
-{
-   db_ = OpenDb(db_name, false, 0);
-   assert(db_);
-   uint64_t one = 1;
-   EncodeFixed64(_one, one);
-   _one_slice = Slice(_one, sizeof(uint64_t));
-  }
+  class Collocators {
+  private:
+    WriteOptions merge_option_; // for merge
+    char _one[sizeof(uint64_t)];
+    Slice _one_slice;
+  
+  protected:
+    std::shared_ptr<DB> db_;
 
-  virtual ~Collocators() {}
+    WriteOptions put_option_;
+    ReadOptions get_option_;
+    WriteOptions delete_option_;
 
-  // public interface of Collocators.
-  // All four functions return false
-  // if the underlying level db operation failed.
+    uint64_t default_;
 
-  // mapped to a levedb Put
-  bool set(const std::string& key, uint64_t value) {
-    // just treat the internal rep of int64 as the string
-    char buf[sizeof(value)];
-    EncodeFixed64(buf, value);
-    Slice slice(buf, sizeof(value));
-    auto s = db_->Put(put_option_, key, slice);
+    std::shared_ptr<DB> OpenDb(const char *dbname);
 
-    if (s.ok()) {
-      return true;
-    } else {
-      std::cerr << s.ToString() << std::endl;
-      return false;
-    }
-  }
+  public:
+    Collocators(const char *db_name);
 
-  DB *getDb() {
-    return db_.get();
-  }
+    ~Collocators();
 
-  // mapped to a rocksdb Delete
-  bool remove(const std::string& key) {
-    auto s = db_->Delete(delete_option_, key);
+    // public interface of Collocators.
+    // All four functions return false
+    // if the underlying level db operation failed.
 
-    if (s.ok()) {
-      return true;
-    } else {
-      std::cerr << s.ToString() << std::endl;
-      return false;
-    }
-  }
+    // mapped to a levedb Put
+    bool set(const std::string& key, uint64_t value) {
+      // just treat the internal rep of int64 as the string
+      char buf[sizeof(value)];
+      EncodeFixed64(buf, value);
+      Slice slice(buf, sizeof(value));
+      auto s = db_->Put(put_option_, key, slice);
 
-  // mapped to a rocksdb Get
-  bool get(const std::string& key, uint64_t* value) {
-    std::string str;
-    auto s = db_->Get(get_option_, key, &str);
-
-    if (s.IsNotFound()) {
-      // return default value if not found;
-      *value = default_;
-      return true;
-    } else if (s.ok()) {
-      // deserialization
-      if (str.size() != sizeof(uint64_t)) {
-        std::cerr << "value corruption\n";
+      if (s.ok()) {
+        return true;
+      } else {
+        std::cerr << s.ToString() << std::endl;
         return false;
       }
-      *value = DecodeFixed64(&str[0]);
-      return true;
-    } else {
-      std::cerr << s.ToString() << std::endl;
-      return false;
     }
+
+    DB *getDb() {
+      return db_.get();
+    }
+
+    // mapped to a rocksdb Delete
+    bool remove(const std::string& key) {
+      auto s = db_->Delete(delete_option_, key);
+
+      if (s.ok()) {
+        return true;
+      } else {
+        std::cerr << s.ToString() << std::endl;
+        return false;
+      }
+    }
+
+    // mapped to a rocksdb Get
+    bool get(const std::string& key, uint64_t* value) {
+      std::string str;
+      auto s = db_->Get(get_option_, key, &str);
+
+      if (s.IsNotFound()) {
+        // return default value if not found;
+        *value = default_;
+        return true;
+      } else if (s.ok()) {
+        // deserialization
+        if (str.size() != sizeof(uint64_t)) {
+          std::cerr << "value corruption\n";
+          return false;
+        }
+        *value = DecodeFixed64(&str[0]);
+        return true;
+      } else {
+        std::cerr << s.ToString() << std::endl;
+        return false;
+      }
+    }
+
+
+    uint64_t get(const uint32_t w1, const uint32_t w2, const int8_t dist) {
+      char encoded_key[sizeof(uint64_t)];
+      EncodeFixed64(encoded_key, encodeCollocation(w1,w2,dist));
+      uint64_t value = default_;
+      get(std::string(encoded_key, 8), &value);
+      return value;
+    }
+
+    virtual void inc(const std::string& key) {
+      db_->Merge(merge_option_, key, _one_slice);
+    }
+
+    void inc(const uint64_t key) {
+      char encoded_key[sizeof(uint64_t)];
+      EncodeFixed64(encoded_key, key);
+      db_->Merge(merge_option_, std::string(encoded_key, 8), _one_slice);
+    }
+
+    virtual void inc(const uint32_t w1, const uint32_t w2, const uint8_t dist);
+
+   
+    // mapped to a rocksdb Merge operation
+    virtual bool add(const std::string& key, uint64_t value) {
+      char encoded[sizeof(uint64_t)];
+      EncodeFixed64(encoded, value);
+      Slice slice(encoded, sizeof(uint64_t));
+      auto s = db_->Merge(merge_option_, key, slice);
+
+      if (s.ok()) {
+        return true;
+      } else {
+        std::cerr << s.ToString() << std::endl;
+        return false;
+      }
+    }
+
+    CollocatorIterator* SeekIterator(uint64_t w1, uint64_t w2, int8_t dist);
+  };
+
+  rocksdb::Collocators::Collocators(const char *db_name) {
+    std::cout << "Test merge-based counters... " << db_name << "\n";
+    db_ = OpenDb(db_name);
+    assert(db_);
+    uint64_t one = 1;
+    EncodeFixed64(_one, one);
+    _one_slice = Slice(_one, sizeof(uint64_t));
+  }
+  
+  rocksdb::CollocatorIterator::~CollocatorIterator() {
+    std::cout << "destroying itera\n";
   }
 
-
-  uint64_t get(const uint32_t w1, const uint32_t w2, const int8_t dist) {
-    char encoded_key[sizeof(uint64_t)];
-    EncodeFixed64(encoded_key, encodeCollocation(w1,w2,dist));
-    uint64_t value = default_;
-    get(std::string(encoded_key, 8), &value);
-    return value;
+  rocksdb::Collocators::~Collocators() {
+    std::cout << "destroying coll\n";
   }
 
-  virtual void inc(const std::string& key) {
-    db_->Merge(merge_option_, key, _one_slice);
-  }
-
-  virtual void inc(const uint64_t key) {
-    char encoded_key[sizeof(uint64_t)];
-    EncodeFixed64(encoded_key, key);
-    db_->Merge(merge_option_, std::string(encoded_key, 8), _one_slice);
-  }
-
-  virtual void inc(const uint32_t w1, const uint32_t w2, const uint8_t dist) {
+  void rocksdb::Collocators::inc(const uint32_t w1, const uint32_t w2, const uint8_t dist) {
     inc(encodeCollocation(w1, w2, dist));
   }
-
-  // mapped to a rocksdb Merge operation
-  virtual bool add(const std::string& key, uint64_t value) {
-    char encoded[sizeof(uint64_t)];
-    EncodeFixed64(encoded, value);
-    Slice slice(encoded, sizeof(uint64_t));
-    auto s = db_->Merge(merge_option_, key, slice);
-
-    if (s.ok()) {
-      return true;
-    } else {
-      std::cerr << s.ToString() << std::endl;
-      return false;
-    }
+    
+  std::shared_ptr<DB> rocksdb::Collocators::OpenDb(const char *dbname) {
+		std::cout << "Test merge-based counters... " << dbname << "\n";
+		DB* db;
+		Options options;
+		options.create_if_missing = true;
+		options.merge_operator = std::make_shared<CountMergeOperator>();
+		options.max_successive_merges = 0;
+		Status s;
+		//  DestroyDB(dbname, Options());
+		s = DB::Open(options, dbname, &db);
+		if (!s.ok()) {
+			std::cerr << s.ToString() << std::endl;
+			assert(false);
+		}
+		return std::shared_ptr<DB>(db);
   }
 
-  virtual CollocatorIterator* SeekIterator(uint64_t w1, uint64_t w2, int8_t dist) {
+  CollocatorIterator* rocksdb::Collocators::SeekIterator(uint64_t w1, uint64_t w2, int8_t dist) {
     ReadOptions options;
     options.prefix_same_as_start = true;  
     char prefixc[sizeof(uint64_t)];
@@ -298,53 +332,8 @@
     return cit;
   }
 
+  rocksdb::Slice rocksdb::CollocatorIterator::key() const { return base_iterator_->key(); }
+  rocksdb::Slice rocksdb::CollocatorIterator::value() const { return base_iterator_->value(); }
+  rocksdb::Status rocksdb::CollocatorIterator::status() const { return base_iterator_->status(); }
+
 };
-
-namespace {
-  void dumpDb(Collocators counters) {
-    auto it = std::unique_ptr<CollocatorIterator>(counters.SeekIterator(1000,0,0));
-    for (; it->Valid(); it->Next()) {
-      uint64_t value = DecodeFixed64(it->value().data());
-      uint64_t key = DecodeFixed64(it->key().data());
-      std::cout << "w1:" << W1(key) << ", w2:" << W2(key) << ", dist:" << (int32_t) DIST(key) << " - count:" << value << std::endl;
-    }
-    assert(it->status().ok());  // Check for any errors found during the scan
-  }
-
-  void testCollocators(Collocators& counters) {
-    counters.inc(100,200,5);
-    counters.inc(1000,2000,-5);
-    counters.inc(1000,2000,5);
-    counters.inc(1000,2500,-3);
-    counters.inc(1000,2500,4);
-    counters.inc(1000,2900,3);
-
-    counters.inc(1001,2900,3);
-
-    for(int i=0; i<10000; i++)
-      counters.inc(rand()%1010,rand()%1010,rand()%10-5);
-
-    //  dumpDb(db);
-
-    counters.inc(100,200,5);
-    counters.inc(1000,2000,5);
-    counters.inc(1000,2500,4);
-    counters.inc(1000,2900,3);
-
-    counters.inc(1001,2900,3);
-
-    dumpDb(counters);
-  }
-
-  void runTest(int argc, const std::string& dbname, const bool use_ttl = false) {
-    std::cout << "Test merge-based counters... \n";
-    Collocators counters(dbname);
-    testCollocators(counters);
-  }
-}  // namespace
-
-int main(int argc, char *argv[]) {
-  runTest(argc, "/tmp/merge_testdb");
-  printf("Passed all tests!\n");
-  return 0;
-}
diff --git a/collocatordb.h b/collocatordb.h
new file mode 100644
index 0000000..72ab00d
--- /dev/null
+++ b/collocatordb.h
@@ -0,0 +1,38 @@
+#include <typeinfo>
+#include <stdint.h>
+#include "rocksdb/cache.h"
+#include "rocksdb/comparator.h"
+#include "rocksdb/db.h"
+#include "rocksdb/env.h"
+#include <rocksdb/merge_operator.h>
+#include "rocksdb/utilities/db_ttl.h"
+#include "merge_operators.h"
+
+#define IS_BIG_ENDIAN (*(uint16_t *)"\0\xff" < 0x100)
+#define encodeCollocation(w1, w2, dist) (((uint64_t)dist << 56) | ((uint64_t)w2 << 24) | w1)
+#define W1(key) (uint64_t)(key & 0xffffff)
+#define W2(key) (uint64_t)((key >> 24) & 0xffffff)
+#define DIST(key) (int8_t)((uint64_t)((key >> 56) & 0xff))
+
+namespace rocksdb {
+    class CollocatorIterator : public Iterator  {
+    public:
+        CollocatorIterator(const Iterator& it);
+        void SeekToFirst();
+        void SeekToLast();
+        void Seek(const rocksdb::Slice&);
+        void Prev();
+        bool isValid();
+        uint64_t intValue();
+        uint64_t intKey();
+    };
+    
+    class Collocators {
+    public:
+        Collocators(const char *db_name);
+        ~Collocators();
+        void inc(const uint32_t w1, const uint32_t w2, const uint8_t dist);
+        CollocatorIterator* SeekIterator(uint64_t w1, uint64_t w2, int8_t dist);
+    };
+    
+}
diff --git a/testcdb.cc b/testcdb.cc
new file mode 100644
index 0000000..08da83f
--- /dev/null
+++ b/testcdb.cc
@@ -0,0 +1,52 @@
+#include <typeinfo>
+#include <assert.h>
+#include <memory>
+#include <iostream>
+#include <stdint.h>
+#include "collocatordb.h"
+using namespace rocksdb;
+
+void dumpDb(Collocators& counters) {
+    auto it = std::unique_ptr<CollocatorIterator>(counters.SeekIterator(1000,0,0));
+    for (; it->isValid(); it->Next()) {
+      uint64_t value = it->intValue();
+      uint64_t key = it->intKey();
+      std::cout << "w1:" << W1(key) << ", w2:" << W2(key) << ", dist:" << (int32_t) DIST(key) << " - count:" << value << std::endl;
+    }
+    std::cout << "ready dumping\n";
+  }
+
+  void testCollocators(Collocators& counters) {
+    counters.inc(100,200,5);
+    counters.inc(1000,2000,-5);
+    counters.inc(1000,2000,5);
+    counters.inc(1000,2500,-3);
+    counters.inc(1000,2500,4);
+    counters.inc(1000,2900,3);
+
+    counters.inc(1001,2900,3);
+
+    for(int i=0; i<10000; i++)
+      counters.inc(rand()%1010,rand()%1010,rand()%10-5);
+
+    //  dumpDb(db);
+
+    counters.inc(100,200,5);
+    counters.inc(1000,2000,5);
+    counters.inc(1000,2500,4);
+    counters.inc(1000,2900,3);
+
+    counters.inc(1001,2900,3);
+
+    dumpDb(counters);
+    std::cout << "ready testing\n";
+  }
+
+  
+int main() {
+    Collocators counters = "/tmp/cdb";
+    std::cout << "testing now\n";
+    testCollocators(counters);
+    std::cout << "ready running\n";
+    return 0;
+}
