summaryrefslogtreecommitdiff
path: root/cpp/include/Freeze/Map.h
diff options
context:
space:
mode:
Diffstat (limited to 'cpp/include/Freeze/Map.h')
-rw-r--r--cpp/include/Freeze/Map.h202
1 files changed, 182 insertions, 20 deletions
diff --git a/cpp/include/Freeze/Map.h b/cpp/include/Freeze/Map.h
index e4b06220647..1429b4fb46c 100644
--- a/cpp/include/Freeze/Map.h
+++ b/cpp/include/Freeze/Map.h
@@ -25,6 +25,49 @@ namespace Freeze
{
class IteratorHelper;
+class MapHelper;
+
+
+class MapIndexI;
+class MapHelperI;
+class IteratorHelperI;
+class SharedDb;
+
+class FREEZE_API MapIndexBase : public IceUtil::Shared
+{
+public:
+
+ virtual ~MapIndexBase();
+
+ const std::string& name() const;
+
+ IteratorHelper* untypedFind(const Key&, bool) const;
+ int untypedCount(const Key&) const;
+
+ //
+ // Implemented by the generated code
+ //
+ virtual void marshalKey(const Value&, Key&) const = 0;
+
+protected:
+
+ MapIndexBase(const std::string&);
+
+ Ice::CommunicatorPtr _communicator;
+
+private:
+
+ friend class MapHelperI;
+ friend class IteratorHelperI;
+ friend class SharedDb;
+
+ std::string _name;
+ MapIndexI* _impl;
+ const MapHelperI* _map;
+};
+
+typedef IceUtil::Handle<MapIndexBase> MapIndexBasePtr;
+
class FREEZE_API MapHelper
{
@@ -33,6 +76,7 @@ public:
static MapHelper*
create(const Freeze::ConnectionPtr& connection,
const std::string& dbName,
+ const std::vector<MapIndexBasePtr>&,
bool createDb);
virtual ~MapHelper() = 0;
@@ -61,6 +105,8 @@ public:
virtual void
closeAllIterators() = 0;
+ virtual const MapIndexBasePtr&
+ index(const std::string&) const = 0;
};
@@ -77,6 +123,9 @@ public:
virtual IteratorHelper*
clone() const = 0;
+ virtual const Key*
+ get() const = 0;
+
virtual void
get(const Key*&, const Value*&) const = 0;
@@ -88,13 +137,9 @@ public:
virtual bool
next() const = 0;
-
- virtual bool
- equals(const IteratorHelper&) const = 0;
};
-
//
// Forward declaration
//
@@ -189,14 +234,22 @@ public:
bool operator==(const Iterator& rhs) const
{
- if(_helper.get() != 0 && rhs._helper.get() != 0)
+ if(_helper.get() == rhs._helper.get())
{
- return _helper->equals(*rhs._helper.get());
+ return true;
}
- else
+
+ if(_helper.get() != 0 && rhs._helper.get() != 0)
{
- return _helper.get() == rhs._helper.get();
+ const Key* lhsKey = _helper->get();
+ const Key* rhsKey = rhs._helper->get();
+
+ if(lhsKey != 0 && rhsKey != 0)
+ {
+ return *lhsKey == *rhsKey;
+ }
}
+ return false;
}
bool operator!=(const Iterator& rhs) const
@@ -413,14 +466,22 @@ public:
bool operator==(const ConstIterator& rhs)
{
- if(_helper.get() != 0 && rhs._helper.get() != 0)
+ if(_helper.get() == rhs._helper.get())
{
- return _helper->equals(*rhs._helper);
+ return true;
}
- else
+
+ if(_helper.get() != 0 && rhs._helper.get() != 0)
{
- return _helper.get() == rhs._helper.get();
+ const Key* lhsKey = _helper->get();
+ const Key* rhsKey = rhs._helper->get();
+
+ if(lhsKey != 0 && rhsKey != 0)
+ {
+ return *lhsKey == *rhsKey;
+ }
}
+ return false;
}
bool operator!=(const ConstIterator& rhs)
@@ -565,21 +626,23 @@ public:
// Constructors
//
Map(const Freeze::ConnectionPtr& connection,
- const std::string& dbName,
- bool createDb = true) :
- _helper(MapHelper::create(connection, dbName, createDb)),
+ const std::string& dbName,
+ bool createDb = true) :
_communicator(connection->getCommunicator())
{
+ std::vector<MapIndexBasePtr> indices;
+ _helper.reset(MapHelper::create(connection, dbName, indices, createDb));
}
template <class _InputIterator>
Map(const Freeze::ConnectionPtr& connection,
- const std::string& dbName,
- bool createDb,
- _InputIterator first, _InputIterator last) :
- _helper(new MapHelper(connection, dbName, createDb)),
+ const std::string& dbName,
+ bool createDb,
+ _InputIterator first, _InputIterator last) :
_communicator(connection->getCommunicator())
{
+ std::vector<MapIndexBasePtr> indices;
+ _helper.reset(MapHelper::create(connection, dbName, indices, createDb));
while(first != last)
{
put(*first);
@@ -867,12 +930,111 @@ public:
}
-private:
+protected:
+
+ Map(const Ice::CommunicatorPtr& communicator) :
+ _communicator(communicator)
+ {
+ }
std::auto_ptr<MapHelper> _helper;
const Ice::CommunicatorPtr _communicator;
};
+
+//
+// ReverseMapIndex is used when the map's value is the secondary key
+//
+
+template <typename key_type, typename mapped_type, typename KeyCodec, typename ValueCodec>
+class ReverseMapIndex : public MapIndexBase
+{
+protected:
+
+ ReverseMapIndex(const std::string& name) :
+ MapIndexBase(name)
+ {
+ }
+
+ virtual void marshalKey(const Value& v, Key& k) const
+ {
+ k = v;
+ }
+};
+
+
+template <typename key_type, typename mapped_type, typename KeyCodec, typename ValueCodec>
+class MapWithReverseIndex : public Map<key_type, mapped_type, KeyCodec, ValueCodec>
+{
+public:
+
+ typedef std::pair<const key_type, const mapped_type> value_type;
+ typedef Iterator<key_type, mapped_type, KeyCodec, ValueCodec > iterator;
+ typedef ConstIterator<key_type, mapped_type, KeyCodec, ValueCodec > const_iterator;
+ typedef size_t size_type;
+ typedef ptrdiff_t difference_type;
+
+
+ //
+ // Constructors
+ //
+ MapWithReverseIndex(const Freeze::ConnectionPtr& connection,
+ const std::string& dbName,
+ bool createDb = true) :
+ Map<key_type, mapped_type, KeyCodec, ValueCodec>(connection->getCommunicator())
+ {
+ std::vector<MapIndexBasePtr> indices;
+ indices.push_back(new ReverseMapIndex<key_type, mapped_type, KeyCodec, ValueCodec>("index"));
+
+ _helper.reset(MapHelper::create(connection, dbName, indices, createDb));
+ }
+
+ template <class _InputIterator>
+ MapWithReverseIndex(const Freeze::ConnectionPtr& connection,
+ const std::string& dbName,
+ bool createDb,
+ _InputIterator first, _InputIterator last) :
+ Map<key_type, mapped_type, KeyCodec, ValueCodec>(connection->getCommunicator())
+ {
+ std::vector<MapIndexBasePtr> indices;
+ indices.push_back(new ReverseMapIndex<key_type, mapped_type, KeyCodec, ValueCodec>("index"));
+
+ while(first != last)
+ {
+ put(*first);
+ ++first;
+ }
+ }
+
+ //
+ // Extra functions
+ //
+
+ iterator reverseFind(const mapped_type& k)
+ {
+ Key bytes;
+ ValueCodec::write(k, bytes, _communicator);
+
+ return iterator(_helper->index("index")->untypedFind(bytes, false), _communicator);
+ }
+
+ const_iterator reverseFind(const mapped_type& k) const
+ {
+ Key bytes;
+ ValueCodec::write(k, bytes, _communicator);
+
+ return const_iterator(_helper->index("index")->untypedFind(bytes, true), _communicator);
+ }
+
+ int valueCount(const mapped_type& k) const
+ {
+ Key bytes;
+ ValueCodec::write(k, bytes, _communicator);
+
+ return _helper->index("index")->untypedCount(bytes);
+ }
+};
+
}
//