diff options
Diffstat (limited to 'cpp')
-rw-r--r-- | cpp/include/Freeze/Map.h | 338 | ||||
-rw-r--r-- | cpp/src/Freeze/BackgroundSaveEvictorI.cpp | 41 | ||||
-rw-r--r-- | cpp/src/Freeze/BackgroundSaveEvictorI.h | 25 | ||||
-rw-r--r-- | cpp/src/Freeze/MapI.cpp | 353 | ||||
-rw-r--r-- | cpp/src/Freeze/MapI.h | 58 | ||||
-rw-r--r-- | cpp/src/Freeze/ObjectStore.cpp | 179 | ||||
-rw-r--r-- | cpp/src/Freeze/ObjectStore.h | 35 | ||||
-rw-r--r-- | cpp/src/Freeze/SharedDbEnv.cpp | 7 | ||||
-rw-r--r-- | cpp/src/Freeze/Util.h | 34 | ||||
-rw-r--r-- | cpp/src/slice2freeze/Main.cpp | 735 |
10 files changed, 1012 insertions, 793 deletions
diff --git a/cpp/include/Freeze/Map.h b/cpp/include/Freeze/Map.h index 3a8d548ebe2..6be1a77002f 100644 --- a/cpp/include/Freeze/Map.h +++ b/cpp/include/Freeze/Map.h @@ -20,6 +20,7 @@ // Berkeley DB's DbEnv // class DbEnv; +class Dbt; namespace Freeze { @@ -35,6 +36,7 @@ class SharedDb; class FREEZE_API KeyCompareBase : public IceUtil::Shared { public: + KeyCompareBase(bool); bool compareEnabled() const; @@ -42,6 +44,7 @@ public: virtual int compare(const Key&, const Key&) = 0; private: + const bool _enabled; }; typedef IceUtil::Handle<KeyCompareBase> KeyCompareBasePtr; @@ -49,7 +52,7 @@ typedef IceUtil::Handle<KeyCompareBase> KeyCompareBasePtr; class FREEZE_API MapIndexBase : public KeyCompareBase { public: - + virtual ~MapIndexBase(); const std::string& name() const; @@ -89,9 +92,9 @@ typedef IceUtil::Handle<MapIndexBase> MapIndexBasePtr; class FREEZE_API MapHelper { public: - + static MapHelper* - create(const ConnectionPtr& connection, + create(const ConnectionPtr& connection, const std::string& dbName, const std::string& key, const std::string& value, @@ -99,20 +102,23 @@ public: const std::vector<MapIndexBasePtr>&, bool createDb); - static void - recreate(const ConnectionPtr& connection, + static void + recreate(const ConnectionPtr& connection, const std::string& dbName, const std::string& key, const std::string& value, const KeyCompareBasePtr&, const std::vector<MapIndexBasePtr>&); - + virtual ~MapHelper() = 0; virtual IteratorHelper* find(const Key&, bool) const = 0; virtual IteratorHelper* + find(const Dbt&, bool) const = 0; + + virtual IteratorHelper* lowerBound(const Key&, bool) const = 0; virtual IteratorHelper* @@ -121,12 +127,21 @@ public: virtual void put(const Key&, const Value&) = 0; + virtual void + put(const Dbt&, const Dbt&) = 0; + virtual size_t erase(const Key&) = 0; virtual size_t + erase(const Dbt&) = 0; + + virtual size_t count(const Key&) const = 0; - + + virtual size_t + count(const Dbt&) const = 0; + virtual void clear() = 0; @@ -149,36 +164,37 @@ public: getConnection() const = 0; }; - class FREEZE_API IteratorHelper -{ +{ public: - static IteratorHelper* + static IteratorHelper* create(const MapHelper& m, bool readOnly); - virtual + virtual ~IteratorHelper() ICE_NOEXCEPT_FALSE = 0; virtual IteratorHelper* clone() const = 0; - - virtual const Key* + + virtual const Key* get() const = 0; virtual void get(const Key*&, const Value*&) const = 0; - - virtual void + + virtual void set(const Value&) = 0; virtual void + set(const Dbt&) = 0; + + virtual void erase() = 0; virtual bool next() const = 0; -}; - +}; // // Forward declaration @@ -198,7 +214,7 @@ struct IteratorBase // // Database iterator. This implements a forward iterator with the -// restriction that it's only possible to explicitely write back into +// restriction that it's only possible to explicitly write back into // the database. // // Two iterators are equal if they use the same database and their @@ -275,12 +291,12 @@ public: { return true; } - + if(_helper.get() != 0 && rhs._helper.get() != 0) { const Key* lhsKey = _helper->get(); const Key* rhsKey = rhs._helper->get(); - + if(lhsKey != 0 && rhsKey != 0) { return *lhsKey == *rhsKey; @@ -344,9 +360,8 @@ public: { assert(_helper.get()); - Value v; - ValueCodec::write(value, v, _communicator, _encoding); - _helper->set(v); + ValueCodec v(value, _communicator, _encoding); + _helper->set(v.dbt()); _refValid = false; } @@ -418,8 +433,8 @@ public: typedef value_type& reference; - ConstIterator(IteratorHelper* helper, - const Ice::CommunicatorPtr& communicator, + ConstIterator(IteratorHelper* helper, + const Ice::CommunicatorPtr& communicator, const Ice::EncodingVersion& encoding) : _helper(helper), _communicator(communicator), @@ -510,12 +525,12 @@ public: { return true; } - + if(_helper.get() != 0 && rhs._helper.get() != 0) { const Key* lhsKey = _helper->get(); const Key* rhsKey = rhs._helper->get(); - + if(lhsKey != 0 && rhsKey != 0) { return *lhsKey == *rhsKey; @@ -553,7 +568,7 @@ public: { key_type key; mapped_type value; - + getCurrentValue(key, value); // @@ -629,8 +644,9 @@ template<typename key_type, typename KeyCodec, typename Compare> class KeyCompare : public KeyCompareBase { public: + KeyCompare(const Compare& mapCompare, - const Ice::CommunicatorPtr& communicator, + const Ice::CommunicatorPtr& communicator, const Ice::EncodingVersion& encoding) : KeyCompareBase(true), _compare(mapCompare), @@ -658,20 +674,23 @@ public: return 0; } } + private: + Compare _compare; const Ice::CommunicatorPtr _communicator; const Ice::EncodingVersion _encoding; }; // -// Partial template specialization: +// Partial template specialization: // do nothing for the IceEncodingCompare comparator // template<typename key_type, typename KeyCodec> class KeyCompare<key_type, KeyCodec, IceEncodingCompare> : public KeyCompareBase { public: + KeyCompare(const IceEncodingCompare&, const Ice::CommunicatorPtr&, const Ice::EncodingVersion&): KeyCompareBase(false) {} @@ -691,6 +710,7 @@ template<typename key_type, typename KeyCodec, typename Compare> class MapIndex : public MapIndexBase { public: + virtual int compare(const Key& dbKey1, const Key& dbKey2) { key_type key1; @@ -713,23 +733,26 @@ public: } protected: + MapIndex(const std::string& mapName, const Compare& mapCompare) : MapIndexBase(mapName, true), _compare(mapCompare) {} private: + Compare _compare; }; // -// Partial template specialization: +// Partial template specialization: // do nothing for the IceEncodingCompare comparator // template<typename key_type, typename KeyCodec> class MapIndex<key_type, KeyCodec, IceEncodingCompare> : public MapIndexBase { public: + virtual int compare(const Key&, const Key&) { assert(0); @@ -737,11 +760,162 @@ public: } protected: + MapIndex(const std::string& mapName, const IceEncodingCompare&): MapIndexBase(mapName, false) {} }; +class FREEZE_API MapCodecBase +{ +public: + + const Dbt& dbt() const { return *_dbt; } + +protected: + + MapCodecBase(const Ice::CommunicatorPtr&, const Ice::EncodingVersion&); + ~MapCodecBase(); + + void init(); + + IceInternal::BasicStream _stream; + Dbt* _dbt; +}; + +// +// Codec template for all key types. Marshaled keys are NOT encapsulated. +// +template<typename T> +class MapKeyCodec : public MapCodecBase +{ +public: + + // + // Use the constructor to marshal a value while avoiding unnecessary copies of the + // marshaled data. The inherited dbt() accessor provides a Dbt value initialized with + // the marshaled bytes. + // + MapKeyCodec(const T& v, const Ice::CommunicatorPtr& communicator, const Ice::EncodingVersion& encoding) : + MapCodecBase(communicator, encoding) + { + _stream.write(v); + init(); + } + + template<typename U> static void write(const U& v, std::vector<Ice::Byte>& bytes, + const Ice::CommunicatorPtr& communicator, + const Ice::EncodingVersion& encoding) + { + IceInternal::BasicStream stream(IceInternal::getInstance(communicator).get(), encoding, true); + stream.write(v); + std::vector<Ice::Byte>(stream.b.begin(), stream.b.end()).swap(bytes); + } + + template<typename U> static void read(U& v, const std::vector<Ice::Byte>& bytes, + const Ice::CommunicatorPtr& communicator, + const Ice::EncodingVersion& encoding) + { + IceInternal::BasicStream stream(IceInternal::getInstance(communicator).get(), encoding, &bytes[0], + &bytes[0] + bytes.size()); + stream.read(v); + } +}; + +// +// Codec template for all value types except those that use classes. Marshaled values are encapsulated. +// +template<typename T> +class MapValueCodec : public MapCodecBase +{ +public: + + // + // Use the constructor to marshal a value while avoiding unnecessary copies of the + // marshaled data. The inherited dbt() accessor provides a Dbt value initialized with + // the marshaled bytes. + // + MapValueCodec(const T& v, const Ice::CommunicatorPtr& communicator, const Ice::EncodingVersion& encoding) : + MapCodecBase(communicator, encoding) + { + _stream.startWriteEncaps(); + _stream.write(v); + _stream.endWriteEncaps(); + init(); + } + + template<typename U> static void write(const U& v, std::vector<Ice::Byte>& bytes, + const Ice::CommunicatorPtr& communicator, + const Ice::EncodingVersion& encoding) + { + IceInternal::BasicStream stream(IceInternal::getInstance(communicator).get(), encoding, true); + stream.startWriteEncaps(); + stream.write(v); + stream.endWriteEncaps(); + std::vector<Ice::Byte>(stream.b.begin(), stream.b.end()).swap(bytes); + } + + template<typename U> static void read(U& v, const std::vector<Ice::Byte>& bytes, + const Ice::CommunicatorPtr& communicator, + const Ice::EncodingVersion& encoding) + { + IceInternal::BasicStream stream(IceInternal::getInstance(communicator).get(), encoding, &bytes[0], + &bytes[0] + bytes.size()); + stream.startReadEncaps(); + stream.read(v); + stream.endReadEncaps(); + } +}; + +// +// Codec template for all value types that use classes. Marshaled values are encapsulated. +// +template<typename T> +class MapObjectValueCodec : public MapCodecBase +{ +public: + + // + // Use the constructor to marshal a value while avoiding unnecessary copies of the + // marshaled data. The inherited dbt() accessor provides a Dbt value initialized with + // the marshaled bytes. + // + MapObjectValueCodec(const T& v, const Ice::CommunicatorPtr& communicator, const Ice::EncodingVersion& encoding) : + MapCodecBase(communicator, encoding) + { + _stream.startWriteEncaps(); + _stream.write(v); + _stream.writePendingObjects(); + _stream.endWriteEncaps(); + init(); + } + + template<typename U> static void write(const U& v, std::vector<Ice::Byte>& bytes, + const Ice::CommunicatorPtr& communicator, + const Ice::EncodingVersion& encoding) + { + IceInternal::BasicStream stream(IceInternal::getInstance(communicator).get(), encoding, true); + stream.startWriteEncaps(); + stream.write(v); + stream.writePendingObjects(); + stream.endWriteEncaps(); + std::vector<Ice::Byte>(stream.b.begin(), stream.b.end()).swap(bytes); + } + + template<typename U> static void read(U& v, const std::vector<Ice::Byte>& bytes, + const Ice::CommunicatorPtr& communicator, + const Ice::EncodingVersion& encoding) + { + IceInternal::BasicStream stream(IceInternal::getInstance(communicator).get(), encoding, &bytes[0], + &bytes[0] + bytes.size()); + stream.sliceObjects(false); + stream.startReadEncaps(); + stream.read(v); + stream.readPendingObjects(); + stream.endReadEncaps(); + } +}; + // // A sorted map, similar to a std::map, with one notable difference: // operator[] is not provided. @@ -749,7 +923,7 @@ protected: // // TODO: implement bidirectional iterators. // -template<typename key_type, typename mapped_type, +template<typename key_type, typename mapped_type, typename KeyCodec, typename ValueCodec, typename Compare = IceEncodingCompare> class Map @@ -777,23 +951,26 @@ public: // // Constructors // - Map(const Freeze::ConnectionPtr& connection, + Map(const Freeze::ConnectionPtr& connection, const std::string& dbName, + const std::string& keyTypeId, + const std::string& valueTypeId, bool createDb = true, const Compare& compare = Compare()) : _communicator(connection->getCommunicator()), _encoding(connection->getEncoding()) - { + { KeyCompareBasePtr keyCompare = new KeyCompare<key_type, KeyCodec, Compare>(compare, _communicator, _encoding); std::vector<MapIndexBasePtr> indices; - _helper.reset(MapHelper::create(connection, dbName, KeyCodec::typeId(), ValueCodec::typeId(), keyCompare, - indices, createDb)); + _helper.reset(MapHelper::create(connection, dbName, keyTypeId, valueTypeId, keyCompare, indices, createDb)); } template<class _InputIterator> - Map(const Freeze::ConnectionPtr& connection, - const std::string& dbName, + Map(const Freeze::ConnectionPtr& connection, + const std::string& dbName, + const std::string& keyTypeId, + const std::string& valueTypeId, bool createDb, _InputIterator first, _InputIterator last, const Compare& compare = Compare()) : @@ -804,8 +981,7 @@ public: std::vector<MapIndexBasePtr> indices; - _helper.reset(MapHelper::create(connection, dbName, KeyCodec::typeId(), ValueCodec::typeId(), keyCompare, - indices, createDb)); + _helper.reset(MapHelper::create(connection, dbName, keyTypeId, valueTypeId, keyCompare, indices, createDb)); while(first != last) { @@ -818,11 +994,11 @@ public: { } - // static void recreate(const Freeze::ConnectionPtr& connection, + // static void recreate(const Freeze::ConnectionPtr& connection, // const std::string& dbName, // const Compare& compare = Compare()) // { - // KeyCompareBasePtr keyCompare = new KeyCompare<key_type, KeyCodec, Compare>(compare, + // KeyCompareBasePtr keyCompare = new KeyCompare<key_type, KeyCodec, Compare>(compare, // connection->getCommunicator(), // connection->getEncoding()); @@ -863,7 +1039,7 @@ public: { return !(*this == rhs); } - + void swap(Map& rhs) { MapHelper* tmp = _helper.release(); @@ -945,24 +1121,22 @@ public: // //allocator_type get_allocator() const; // - + iterator insert(iterator /*position*/, const value_type& key) { // // position is ignored. // - Key k; - KeyCodec::write(key.first, k, _communicator, _encoding); - - iterator r = iterator(_helper->find(k, false), _communicator, _encoding); + KeyCodec k(key.first, _communicator, _encoding); + + iterator r = iterator(_helper->find(k.dbt(), false), _communicator, _encoding); if(r == end()) { - Value v; - ValueCodec::write(key.second, v, _communicator, _encoding); - - _helper->put(k, v); - r = iterator(_helper->find(k, false), _communicator, _encoding); + ValueCodec v(key.second, _communicator, _encoding); + + _helper->put(k.dbt(), v.dbt()); + r = iterator(_helper->find(k.dbt(), false), _communicator, _encoding); } return r; @@ -970,20 +1144,18 @@ public: std::pair<iterator, bool> insert(const value_type& key) { - Key k; - KeyCodec::write(key.first, k, _communicator, _encoding); + KeyCodec k(key.first, _communicator, _encoding); - iterator r = iterator(_helper->find(k, false), _communicator, _encoding); + iterator r = iterator(_helper->find(k.dbt(), false), _communicator, _encoding); bool inserted = false; if(r == end()) { - Value v; - ValueCodec::write(key.second, v, _communicator, _encoding); - - _helper->put(k, v); + ValueCodec v(key.second, _communicator, _encoding); + + _helper->put(k.dbt(), v.dbt()); inserted = true; - r = iterator(_helper->find(k, false), _communicator, _encoding); + r = iterator(_helper->find(k.dbt(), false), _communicator, _encoding); } return std::pair<iterator, bool>(r, inserted); @@ -1004,12 +1176,10 @@ public: // // insert or replace // - Key k; - Value v; - KeyCodec::write(key.first, k, _communicator, _encoding); - ValueCodec::write(key.second, v, _communicator, _encoding); + KeyCodec k(key.first, _communicator, _encoding); + ValueCodec v(key.second, _communicator, _encoding); - _helper->put(k, v); + _helper->put(k.dbt(), v.dbt()); } template <typename InputIterator> @@ -1030,10 +1200,9 @@ public: size_type erase(const key_type& key) { - Key k; - KeyCodec::write(key, k, _communicator, _encoding); + KeyCodec k(key, _communicator, _encoding); - return _helper->erase(k); + return _helper->erase(k.dbt()); } void erase(iterator first, iterator last) @@ -1050,7 +1219,6 @@ public: _helper->clear(); } - // // destroy is not a standard function // @@ -1069,26 +1237,23 @@ public: iterator find(const key_type& key) { - Key k; - KeyCodec::write(key, k, _communicator, _encoding); + KeyCodec k(key, _communicator, _encoding); - return iterator(_helper->find(k, false), _communicator, _encoding); + return iterator(_helper->find(k.dbt(), false), _communicator, _encoding); } const_iterator find(const key_type& key) const { - Key k; - KeyCodec::write(key, k, _communicator, _encoding); + KeyCodec k(key, _communicator, _encoding); - return const_iterator(_helper->find(k, true), _communicator, _encoding); + return const_iterator(_helper->find(k.dbt(), true), _communicator, _encoding); } size_type count(const key_type& key) const { - Key k; - KeyCodec::write(key, k, _communicator, _encoding); - - return _helper->count(k); + KeyCodec k(key, _communicator, _encoding); + + return _helper->count(k.dbt()); } iterator lower_bound(const key_type& key) @@ -1098,7 +1263,7 @@ public: return iterator(_helper->lowerBound(k, false), _communicator, _encoding); } - + const_iterator lower_bound(const key_type& key) const { Key k; @@ -1114,7 +1279,7 @@ public: return iterator(_helper->upperBound(k, false), _communicator, _encoding); } - + const_iterator upper_bound(const key_type& key) const { Key k; @@ -1122,20 +1287,18 @@ public: return iterator(_helper->upperBound(k, true), _communicator, _encoding); } - + std::pair<iterator, iterator> equal_range(const key_type& key) { return std::make_pair(lower_bound(key), upper_bound(key)); } - std::pair<const_iterator, const_iterator> - equal_range(const key_type& key) const + std::pair<const_iterator, const_iterator> equal_range(const key_type& key) const { return std::make_pair(lower_bound(key), upper_bound(key)); } - const Ice::CommunicatorPtr& - communicator() const + const Ice::CommunicatorPtr& communicator() const { return _communicator; } @@ -1164,4 +1327,3 @@ protected: } #endif - diff --git a/cpp/src/Freeze/BackgroundSaveEvictorI.cpp b/cpp/src/Freeze/BackgroundSaveEvictorI.cpp index f37d44bad7e..3216f21cfc8 100644 --- a/cpp/src/Freeze/BackgroundSaveEvictorI.cpp +++ b/cpp/src/Freeze/BackgroundSaveEvictorI.cpp @@ -889,7 +889,7 @@ Freeze::BackgroundSaveEvictorI::run() const size_t size = allObjects.size(); - deque<StreamedObject> streamedObjectQueue; + deque<StreamedObjectPtr> streamedObjectQueue; Long streamStart = IceUtil::Time::now(IceUtil::Time::Monotonic).toMilliSeconds(); @@ -927,8 +927,8 @@ Freeze::BackgroundSaveEvictorI::run() { size_t index = streamedObjectQueue.size(); streamedObjectQueue.resize(index + 1); - StreamedObject& obj = streamedObjectQueue[index]; - stream(element, streamStart, obj); + streamedObjectQueue[index] = new StreamedObject; + stream(element, streamStart, streamedObjectQueue[index]); element->status = dead; deadObjects.push_back(element); @@ -993,8 +993,8 @@ Freeze::BackgroundSaveEvictorI::run() { size_t index = streamedObjectQueue.size(); streamedObjectQueue.resize(index + 1); - StreamedObject& obj = streamedObjectQueue[index]; - stream(element, streamStart, obj); + streamedObjectQueue[index] = new StreamedObject; + stream(element, streamStart, streamedObjectQueue[index]); element->status = clean; } @@ -1010,8 +1010,8 @@ Freeze::BackgroundSaveEvictorI::run() size_t index = streamedObjectQueue.size(); streamedObjectQueue.resize(index + 1); - StreamedObject& obj = streamedObjectQueue[index]; - stream(element, streamStart, obj); + streamedObjectQueue[index] = new StreamedObject; + stream(element, streamStart, streamedObjectQueue[index]); element->status = dead; deadObjects.push_back(element); @@ -1095,8 +1095,14 @@ Freeze::BackgroundSaveEvictorI::run() { for(size_t i = 0; i < txSize; i++) { - StreamedObject& obj = streamedObjectQueue[i]; - obj.store->save(obj.key, obj.value, obj.status, tx); + StreamedObjectPtr obj = streamedObjectQueue[i]; + Dbt key, value; + obj->key->getDbt(key); + if(obj->value) + { + obj->value->getDbt(value); + } + obj->store->save(key, value, obj->status, tx); } } catch(...) @@ -1117,9 +1123,7 @@ Freeze::BackgroundSaveEvictorI::run() out << "committed transaction " << hex << txnId << dec; } - streamedObjectQueue.erase - (streamedObjectQueue.begin(), - streamedObjectQueue.begin() + txSize); + streamedObjectQueue.erase(streamedObjectQueue.begin(), streamedObjectQueue.begin() + txSize); if(_trace >= 1) { @@ -1350,24 +1354,25 @@ Freeze::BackgroundSaveEvictorI::addToModifiedQueue(const BackgroundSaveEvictorEl void -Freeze::BackgroundSaveEvictorI::stream(const BackgroundSaveEvictorElementPtr& element, Long streamStart, StreamedObject& obj) +Freeze::BackgroundSaveEvictorI::stream(const BackgroundSaveEvictorElementPtr& element, Long streamStart, + const StreamedObjectPtr& obj) { assert(element->status != dead); - obj.status = element->status; - obj.store = &element->store; + obj->status = element->status; + obj->store = &element->store; const Identity& ident = element->cachePosition->first; - ObjectStoreBase::marshal(ident, obj.key, _communicator, _encoding); + obj->key = new ObjectStoreBase::KeyMarshaler(ident, _communicator, _encoding); if(element->status != destroyed) { - bool keepStats = obj.store->keepStats(); + const bool keepStats = obj->store->keepStats(); if(keepStats) { EvictorIBase::updateStats(element->rec.stats, streamStart); } - ObjectStoreBase::marshal(element->rec, obj.value, _communicator, _encoding, keepStats); + obj->value = new ObjectStoreBase::ValueMarshaler(element->rec, _communicator, _encoding, keepStats); } } diff --git a/cpp/src/Freeze/BackgroundSaveEvictorI.h b/cpp/src/Freeze/BackgroundSaveEvictorI.h index 12037c53275..51001a28385 100644 --- a/cpp/src/Freeze/BackgroundSaveEvictorI.h +++ b/cpp/src/Freeze/BackgroundSaveEvictorI.h @@ -130,13 +130,30 @@ public: // virtual void run(); - struct StreamedObject + struct StreamedObject : public IceUtil::Shared { - Key key; - Value value; + StreamedObject() : + key(0), value(0) + { + } + + ~StreamedObject() + { + delete key; + delete value; + } + + ObjectStoreBase::KeyMarshaler* key; + ObjectStoreBase::ValueMarshaler* value; Ice::Byte status; ObjectStore<BackgroundSaveEvictorElement>* store; + + private: + + StreamedObject(const StreamedObject&) {} + void operator=(const StreamedObject&) {} }; + typedef IceUtil::Handle<StreamedObject> StreamedObjectPtr; protected: @@ -154,7 +171,7 @@ private: void addToModifiedQueue(const BackgroundSaveEvictorElementPtr&); void fixEvictPosition(const BackgroundSaveEvictorElementPtr&); - void stream(const BackgroundSaveEvictorElementPtr&, Ice::Long, StreamedObject&); + void stream(const BackgroundSaveEvictorElementPtr&, Ice::Long, const StreamedObjectPtr&); // // The _evictorList contains a list of all objects we keep, diff --git a/cpp/src/Freeze/MapI.cpp b/cpp/src/Freeze/MapI.cpp index effaa167982..38fe535e7d6 100644 --- a/cpp/src/Freeze/MapI.cpp +++ b/cpp/src/Freeze/MapI.cpp @@ -22,7 +22,6 @@ using namespace std; using namespace Ice; using namespace Freeze; - // // MapIndexBase (from Map.h) // @@ -51,7 +50,6 @@ Freeze::MapIndexBase::begin(bool ro) const return _impl->begin(ro, *_map); } - IteratorHelper* Freeze::MapIndexBase::untypedFind(const Key& k, bool ro, bool onlyDups) const { @@ -70,7 +68,7 @@ Freeze::MapIndexBase::untypedUpperBound(const Key& k, bool ro) const return _impl->untypedUpperBound(k, ro, *_map); } -int +int Freeze::MapIndexBase::untypedCount(const Key& k) const { return _impl->untypedCount(k, _map->connection()); @@ -94,7 +92,7 @@ Freeze::KeyCompareBase::compareEnabled() const // /*static*/ Freeze::MapHelper* -Freeze::MapHelper::create(const Freeze::ConnectionPtr& connection, +Freeze::MapHelper::create(const Freeze::ConnectionPtr& connection, const string& dbName, const string& key, const string& value, @@ -107,7 +105,7 @@ Freeze::MapHelper::create(const Freeze::ConnectionPtr& connection, } /*static*/ void -Freeze::MapHelper::recreate(const Freeze::ConnectionPtr& connection, +Freeze::MapHelper::recreate(const Freeze::ConnectionPtr& connection, const string& dbName, const string& key, const string& value, @@ -139,7 +137,7 @@ Freeze::MapHelper::recreate(const Freeze::ConnectionPtr& connection, keyDbt.set_flags(DB_DBT_REALLOC); Dbt valueDbt; valueDbt.set_flags(DB_DBT_REALLOC); - + try { for(;;) @@ -151,10 +149,9 @@ Freeze::MapHelper::recreate(const Freeze::ConnectionPtr& connection, tx = 0; tx = connectionI->beginTransaction(); } - + DbTxn* txn = connectionI->dbTxn(); - if(connectionI->trace() >= 2) { Trace out(connectionI->communicator()->getLogger(), "Freeze.Map"); @@ -165,7 +162,7 @@ Freeze::MapHelper::recreate(const Freeze::ConnectionPtr& connection, if(p != catalogIndexList.end()) { const StringSeq& indices = p->second; - + for(size_t i = 0; i < indices.size(); ++i) { try @@ -181,7 +178,7 @@ Freeze::MapHelper::recreate(const Freeze::ConnectionPtr& connection, } catalogIndexList.erase(p); } - + // // Rename existing database // @@ -194,22 +191,20 @@ Freeze::MapHelper::recreate(const Freeze::ConnectionPtr& connection, } connectionI->dbEnv()->getEnv()->dbrename(txn, dbName.c_str(), 0, oldDbName.c_str(), 0); - + // // Fortunately, DB closes oldDb automatically when it goes out of scope // Db oldDb(connectionI->dbEnv()->getEnv(), 0); - // // Berkeley DB expects file paths to be UTF8 encoded. // - oldDb.open(txn, - IceUtil::nativeToUTF8(oldDbName, IceUtil::getProcessStringConverter()).c_str(), + oldDb.open(txn, IceUtil::nativeToUTF8(oldDbName, IceUtil::getProcessStringConverter()).c_str(), 0, DB_BTREE, DB_THREAD, FREEZE_DB_MODE); - + IceUtil::UniquePtr<MapDb> newDb(new MapDb(connectionI, dbName, key, value, keyCompare, indices, true)); - + if(connectionI->trace() >= 2) { Trace out(connectionI->communicator()->getLogger(), "Freeze.Map"); @@ -221,7 +216,7 @@ Freeze::MapHelper::recreate(const Freeze::ConnectionPtr& connection, // Dbc* dbc = 0; oldDb.cursor(txn, &dbc, 0); - + try { while(dbc->get(&keyDbt, &valueDbt, DB_NEXT) == 0) @@ -247,7 +242,7 @@ Freeze::MapHelper::recreate(const Freeze::ConnectionPtr& connection, { tx->commit(); } - + break; // for (;;) } catch(const DbDeadlockException& dx) @@ -257,7 +252,7 @@ Freeze::MapHelper::recreate(const Freeze::ConnectionPtr& connection, if(connectionI->deadlockWarning()) { Warning out(connectionI->communicator()->getLogger()); - out << "Deadlock in Freeze::MapHelperI::recreate on Db \"" + out << "Deadlock in Freeze::MapHelperI::recreate on Db \"" << dbName << "\"; retrying ..."; } @@ -282,13 +277,13 @@ Freeze::MapHelper::recreate(const Freeze::ConnectionPtr& connection, { } } - + throw DatabaseException(__FILE__, __LINE__, dx.what()); } catch(...) { if(ownTx && tx != 0) - { + { try { tx->rollback(); @@ -312,24 +307,20 @@ Freeze::MapHelper::recreate(const Freeze::ConnectionPtr& connection, } } - - Freeze::MapHelper::~MapHelper() { } - // // IteratorHelper (from Map.h) // -Freeze::IteratorHelper* +Freeze::IteratorHelper* Freeze::IteratorHelper::create(const MapHelper& m, bool readOnly) { const MapHelperI& actualMap = dynamic_cast<const MapHelperI&>(m); - IceUtil::UniquePtr<IteratorHelperI> r(new IteratorHelperI(actualMap, readOnly, - 0, false)); + IceUtil::UniquePtr<IteratorHelperI> r(new IteratorHelperI(actualMap, readOnly, 0, false)); if(r->next()) { return r.release(); @@ -340,17 +331,36 @@ Freeze::IteratorHelper::create(const MapHelper& m, bool readOnly) } } - Freeze::IteratorHelper::~IteratorHelper() ICE_NOEXCEPT_FALSE { } +// +// MapCodecBase (from Map.h) +// +Freeze::MapCodecBase::MapCodecBase(const Ice::CommunicatorPtr& communicator, const Ice::EncodingVersion& encoding) : + _stream(IceInternal::getInstance(communicator).get(), encoding, true), + _dbt(0) +{ +} + +Freeze::MapCodecBase::~MapCodecBase() +{ + delete _dbt; +} + +void +Freeze::MapCodecBase::init() +{ + _dbt = new Dbt; + initializeInDbt(_stream, *_dbt); +} // // IteratorHelperI // -Freeze::IteratorHelperI::IteratorHelperI(const MapHelperI& m, bool readOnly, +Freeze::IteratorHelperI::IteratorHelperI(const MapHelperI& m, bool readOnly, const MapIndexBasePtr& index, bool onlyDups) : _map(m), @@ -370,7 +380,7 @@ Freeze::IteratorHelperI::IteratorHelperI(const MapHelperI& m, bool readOnly, } DbTxn* txn = _map._connection->dbTxn(); - + if(txn == 0 && !readOnly) { // @@ -405,7 +415,6 @@ Freeze::IteratorHelperI::IteratorHelperI(const MapHelperI& m, bool readOnly, _map._iteratorList.push_back(this); } - Freeze::IteratorHelperI::IteratorHelperI(const IteratorHelperI& it) : _map(it._map), _dbc(0), @@ -429,7 +438,7 @@ Freeze::IteratorHelperI::IteratorHelperI(const IteratorHelperI& it) : ex.message = dx.what(); throw ex; } - + _tx = it._tx; _map._iteratorList.push_back(this); } @@ -439,30 +448,38 @@ Freeze::IteratorHelperI::~IteratorHelperI() ICE_NOEXCEPT_FALSE close(); } - -bool +bool Freeze::IteratorHelperI::find(const Key& key) const { Dbt dbKey; initializeInDbt(key, dbKey); + return find(dbKey); +} + +bool +Freeze::IteratorHelperI::find(const Dbt& key) const +{ + assert((key.get_flags() & DB_DBT_USERMEM) != 0); + Dbt dbKey(key); + #if (DB_VERSION_MAJOR <= 4) || (DB_VERSION_MAJOR == 5 && DB_VERSION_MINOR <= 1) // // When we have a custom-comparison function, Berkeley DB returns // the key on-disk (when it finds one). We disable this behavior: // (ref Oracle SR 5925672.992) // - dbKey.set_flags(DB_DBT_USERMEM | DB_DBT_PARTIAL); + dbKey.set_flags(dbKey.get_flags() | DB_DBT_PARTIAL); #else // // In DB > 5.1 we can not set DB_DBT_PARTIAL in the key Dbt, - // when using DB_SET, we must resize the Dbt key param to hold enought + // when using DB_SET, we must resize the Dbt key param to hold enough // space or Dbc::get fails with DB_BUFFER_SMALL. // - dbKey.set_flags(DB_DBT_USERMEM); - dbKey.set_ulen(static_cast<u_int32_t>(key.size())); + dbKey.set_ulen(dbKey.get_size()); #endif + // - // Keep 0 length since we're not interested in the data + // Keep 0 length since we're not interested in the data. // Dbt dbValue; dbValue.set_flags(DB_DBT_USERMEM | DB_DBT_PARTIAL); @@ -471,7 +488,7 @@ Freeze::IteratorHelperI::find(const Key& key) const { try { - return _dbc->get(&dbKey, &dbValue, DB_SET) == 0; + return _dbc->get(&dbKey, &dbValue, DB_SET) == 0; } catch(const ::DbDeadlockException& dx) { @@ -493,7 +510,7 @@ Freeze::IteratorHelperI::find(const Key& key) const } } -bool +bool Freeze::IteratorHelperI::lowerBound(const Key& key) const { // @@ -539,7 +556,7 @@ Freeze::IteratorHelperI::lowerBound(const Key& key) const { _tx->dead(); } - + DeadlockException ex(__FILE__, __LINE__); ex.message = dx.what(); throw ex; @@ -551,7 +568,7 @@ Freeze::IteratorHelperI::lowerBound(const Key& key) const } } -bool +bool Freeze::IteratorHelperI::upperBound(const Key& key) const { if(lowerBound(key)) @@ -571,13 +588,12 @@ Freeze::IteratorHelperI::upperBound(const Key& key) const } } - Freeze::IteratorHelper* Freeze::IteratorHelperI::clone() const { return new IteratorHelperI(*this); } - + void Freeze::IteratorHelperI::get(const Key*& key, const Value*& value) const { @@ -593,7 +609,7 @@ Freeze::IteratorHelperI::get(const Key*& key, const Value*& value) const Dbt dbKey; initializeOutDbt(_key, dbKey); - + size_t valueSize = _value.size(); if(valueSize < 1024) { @@ -616,7 +632,7 @@ Freeze::IteratorHelperI::get(const Key*& key, const Value*& value) const // Dbt iKey; iKey.set_flags(DB_DBT_USERMEM | DB_DBT_PARTIAL); - + err = _dbc->pget(&iKey, &dbKey, &dbValue, DB_CURRENT); } else @@ -634,7 +650,7 @@ Freeze::IteratorHelperI::get(const Key*& key, const Value*& value) const { throw InvalidPositionException(__FILE__, __LINE__); } - else + else { // // Bug in Freeze @@ -660,7 +676,7 @@ Freeze::IteratorHelperI::get(const Key*& key, const Value*& value) const } } } - + const Freeze::Key* Freeze::IteratorHelperI::get() const { @@ -673,13 +689,13 @@ Freeze::IteratorHelperI::get() const Dbt dbKey; initializeOutDbt(_key, dbKey); - + // // Keep 0 length since we're not interested in the data // Dbt dbValue; dbValue.set_flags(DB_DBT_USERMEM | DB_DBT_PARTIAL); - + for(;;) { try @@ -692,7 +708,7 @@ Freeze::IteratorHelperI::get() const // Dbt iKey; iKey.set_flags(DB_DBT_USERMEM | DB_DBT_PARTIAL); - + err = _dbc->pget(&iKey, &dbKey, &dbValue, DB_CURRENT); } else @@ -709,7 +725,7 @@ Freeze::IteratorHelperI::get() const { throw InvalidPositionException(__FILE__, __LINE__); } - else + else { // // Bug in Freeze @@ -736,24 +752,31 @@ Freeze::IteratorHelperI::get() const } } -void +void Freeze::IteratorHelperI::set(const Value& value) { + Dbt dbValue; + initializeInDbt(value, dbValue); + set(dbValue); +} + +void +Freeze::IteratorHelperI::set(const Dbt& value) +{ if(_indexed) { DatabaseException ex(__FILE__, __LINE__); ex.message = "Cannot set an iterator retrieved through an index"; throw ex; } - + // // key ignored // Dbt dbKey; dbKey.set_flags(DB_DBT_USERMEM); - Dbt dbValue; - initializeInDbt(value, dbValue); + Dbt dbValue(value); if(_tx != 0) { @@ -824,7 +847,7 @@ Freeze::IteratorHelperI::erase() } } -bool +bool Freeze::IteratorHelperI::next() const { return next(false); @@ -891,7 +914,7 @@ Freeze::IteratorHelperI::close() Trace out(_map._connection->communicator()->getLogger(), "Freeze.Map"); out << "closing iterator on Db \"" << _map._dbName << "\""; } - + try { _dbc->close(); @@ -916,17 +939,16 @@ Freeze::IteratorHelperI::cleanup() { _dbc = 0; _map._iteratorList.remove(this); - + // this can raise an exception when committing the transaction // (only for read/write iterators) #ifdef ICE_CPP11 _tx.reset(); #else _tx = 0; -#endif +#endif } - // // IteratorHelperI::Tx // @@ -953,7 +975,6 @@ Freeze::IteratorHelperI::Tx::Tx(const MapHelperI& m) : throw ex; } } - Freeze::IteratorHelperI::Tx::~Tx() ICE_NOEXCEPT_FALSE { @@ -1009,14 +1030,11 @@ Freeze::IteratorHelperI::Tx::dead() _dead = true; } - - // // MapHelperI // - -Freeze::MapHelperI::MapHelperI(const ConnectionIPtr& connection, +Freeze::MapHelperI::MapHelperI(const ConnectionIPtr& connection, const string& dbName, const string& key, const string& value, @@ -1027,26 +1045,25 @@ Freeze::MapHelperI::MapHelperI(const ConnectionIPtr& connection, _db(connection->dbEnv()->getSharedMapDb(dbName, key, value, keyCompare, indices, createDb)), _dbName(dbName), _trace(connection->trace()) -{ - for(vector<MapIndexBasePtr>::const_iterator p = indices.begin(); +{ + for(vector<MapIndexBasePtr>::const_iterator p = indices.begin(); p != indices.end(); ++p) { const MapIndexBasePtr& indexBase = *p; assert(indexBase->_impl != 0); assert(indexBase->_communicator == _connection->communicator()); assert(indexBase->_map == 0); - + #ifdef NDEBUG - _indices.insert(IndexMap::value_type(indexBase->name(), indexBase)); + _indices.insert(IndexMap::value_type(indexBase->name(), indexBase)); #else - bool inserted = - _indices.insert(IndexMap::value_type(indexBase->name(), indexBase)).second; + bool inserted = _indices.insert(IndexMap::value_type(indexBase->name(), indexBase)).second; assert(inserted); #endif indexBase->_map = this; } - + _connection->registerMap(this); } @@ -1060,7 +1077,7 @@ Freeze::MapHelperI::~MapHelperI() { Ice::Error error(_connection->getCommunicator()->getLogger()); error << "Freeze: closing map " << _dbName << " raised: " << ex; - } + } } Freeze::IteratorHelper* @@ -1069,7 +1086,47 @@ Freeze::MapHelperI::find(const Key& k, bool readOnly) const for(;;) { try - { + { + IceUtil::UniquePtr<IteratorHelperI> r(new IteratorHelperI(*this, readOnly, 0, false)); + if(r->find(k)) + { + return r.release(); + } + else + { + return 0; + } + } + catch(const DeadlockException&) + { + if(_connection->dbTxn() != 0) + { + throw; + } + else + { + if(_connection->deadlockWarning()) + { + Warning out(_connection->communicator()->getLogger()); + out << "Deadlock in Freeze::MapHelperI::find on Map \"" + << _dbName << "\"; retrying ..."; + } + + // + // Ignored, try again + // + } + } + } +} + +Freeze::IteratorHelper* +Freeze::MapHelperI::find(const Dbt& k, bool readOnly) const +{ + for(;;) + { + try + { IceUtil::UniquePtr<IteratorHelperI> r(new IteratorHelperI(*this, readOnly, 0, false)); if(r->find(k)) { @@ -1091,7 +1148,7 @@ Freeze::MapHelperI::find(const Key& k, bool readOnly) const if(_connection->deadlockWarning()) { Warning out(_connection->communicator()->getLogger()); - out << "Deadlock in Freeze::MapHelperI::find on Map \"" + out << "Deadlock in Freeze::MapHelperI::find on Map \"" << _dbName << "\"; retrying ..."; } @@ -1109,7 +1166,7 @@ Freeze::MapHelperI::lowerBound(const Key& k, bool readOnly) const for(;;) { try - { + { IceUtil::UniquePtr<IteratorHelperI> r(new IteratorHelperI(*this, readOnly, 0, false)); if(r->lowerBound(k)) { @@ -1131,7 +1188,7 @@ Freeze::MapHelperI::lowerBound(const Key& k, bool readOnly) const if(_connection->deadlockWarning()) { Warning out(_connection->communicator()->getLogger()); - out << "Deadlock in Freeze::MapHelperI::lowerBound on Map \"" + out << "Deadlock in Freeze::MapHelperI::lowerBound on Map \"" << _dbName << "\"; retrying ..."; } @@ -1149,7 +1206,7 @@ Freeze::MapHelperI::upperBound(const Key& k, bool readOnly) const for(;;) { try - { + { IceUtil::UniquePtr<IteratorHelperI> r(new IteratorHelperI(*this, readOnly, 0, false)); if(r->upperBound(k)) { @@ -1171,7 +1228,7 @@ Freeze::MapHelperI::upperBound(const Key& k, bool readOnly) const if(_connection->deadlockWarning()) { Warning out(_connection->communicator()->getLogger()); - out << "Deadlock in Freeze::MapHelperI::upperBound on Map \"" + out << "Deadlock in Freeze::MapHelperI::upperBound on Map \"" << _dbName << "\"; retrying ..."; } @@ -1190,20 +1247,27 @@ Freeze::MapHelperI::put(const Key& key, const Value& value) Dbt dbValue; initializeInDbt(key, dbKey); initializeInDbt(value, dbValue); - + put(dbKey, dbValue); +} + +void +Freeze::MapHelperI::put(const Dbt& key, const Dbt& value) +{ DbTxn* txn = _connection->dbTxn(); if(txn == 0) { closeAllIterators(); } + Dbt dbKey(key); + Dbt dbValue(value); + for(;;) { try { - int err = _db->put(txn, &dbKey, &dbValue, - txn != 0 ? 0 : DB_AUTO_COMMIT); - + int err = _db->put(txn, &dbKey, &dbValue, txn != 0 ? 0 : DB_AUTO_COMMIT); + if(err == 0) { break; @@ -1229,7 +1293,7 @@ Freeze::MapHelperI::put(const Key& key, const Value& value) if(_connection->deadlockWarning()) { Warning out(_connection->communicator()->getLogger()); - out << "Deadlock in Freeze::MapHelperI::put on Map \"" + out << "Deadlock in Freeze::MapHelperI::put on Map \"" << _dbName << "\"; retrying ..."; } @@ -1252,13 +1316,20 @@ Freeze::MapHelperI::erase(const Key& key) { Dbt dbKey; initializeInDbt(key, dbKey); + return erase(dbKey); +} +size_t +Freeze::MapHelperI::erase(const Dbt& key) +{ DbTxn* txn = _connection->dbTxn(); if(txn == 0) { closeAllIterators(); } + Dbt dbKey(key); + for(;;) { try @@ -1267,11 +1338,11 @@ Freeze::MapHelperI::erase(const Key& key) if(err == 0) { - return true; + return 1; } else if(err == DB_NOTFOUND) { - return false; + return 0; } else { @@ -1292,7 +1363,7 @@ Freeze::MapHelperI::erase(const Key& key) if(_connection->deadlockWarning()) { Warning out(_connection->communicator()->getLogger()); - out << "Deadlock in Freeze::MapHelperI::erase on Map \"" + out << "Deadlock in Freeze::MapHelperI::erase on Map \"" << _dbName << "\"; retrying ..."; } @@ -1315,19 +1386,26 @@ Freeze::MapHelperI::count(const Key& key) const { Dbt dbKey; initializeInDbt(key, dbKey); - + return count(dbKey); +} + +size_t +Freeze::MapHelperI::count(const Dbt& key) const +{ + Dbt dbKey(key); + // // Keep 0 length since we're not interested in the data // Dbt dbValue; dbValue.set_flags(DB_DBT_USERMEM | DB_DBT_PARTIAL); - + for(;;) { try { int err = _db->get(_connection->dbTxn(), &dbKey, &dbValue, 0); - + if(err == 0) { return 1; @@ -1355,7 +1433,7 @@ Freeze::MapHelperI::count(const Key& key) const if(_connection->deadlockWarning()) { Warning out(_connection->communicator()->getLogger()); - out << "Deadlock in Freeze::MapHelperI::count on Map \"" + out << "Deadlock in Freeze::MapHelperI::count on Map \"" << _dbName << "\"; retrying ..."; } @@ -1372,7 +1450,7 @@ Freeze::MapHelperI::count(const Key& key) const } } } - + void Freeze::MapHelperI::clear() { @@ -1384,7 +1462,7 @@ Freeze::MapHelperI::clear() Dbt dbKey; dbKey.set_flags(DB_DBT_USERMEM | DB_DBT_PARTIAL); - + Dbt dbValue; dbValue.set_flags(DB_DBT_USERMEM | DB_DBT_PARTIAL); @@ -1393,7 +1471,7 @@ Freeze::MapHelperI::clear() for(;;) { Dbc* dbc = 0; - + try { IteratorHelperI::TxPtr tx; @@ -1444,7 +1522,7 @@ Freeze::MapHelperI::clear() if(_connection->deadlockWarning()) { Warning out(_connection->communicator()->getLogger()); - out << "Deadlock in Freeze::MapHelperI::clear on Map \"" + out << "Deadlock in Freeze::MapHelperI::clear on Map \"" << _dbName << "\"; retrying ..."; } @@ -1497,10 +1575,9 @@ Freeze::MapHelperI::destroy() { if(_dbName == catalogName() || _dbName == catalogIndexListName()) { - throw DatabaseException(__FILE__, __LINE__, - "You cannot destroy the \"" + _dbName + "\" database"); + throw DatabaseException(__FILE__, __LINE__, "You cannot destroy the \"" + _dbName + "\" database"); } - + if(_db == 0) { // @@ -1525,7 +1602,7 @@ Freeze::MapHelperI::destroy() { indexNames.push_back(p->second->name()); } - + closeDb(); for(;;) @@ -1537,12 +1614,12 @@ Freeze::MapHelperI::destroy() Catalog catalog(_connection, catalogName()); catalog.erase(_dbName); - + CatalogIndexList catalogIndexList(_connection, catalogIndexListName()); catalogIndexList.erase(_dbName); - + _connection->dbEnv()->getEnv()->dbremove(txn, _dbName.c_str(), 0, 0); - + // // Remove all indices // @@ -1550,9 +1627,9 @@ Freeze::MapHelperI::destroy() { _connection->removeMapIndex(_dbName, *q); } - + tx.commit(); - + break; // for(;;) } catch(const DbDeadlockException&) @@ -1560,10 +1637,10 @@ Freeze::MapHelperI::destroy() if(_connection->deadlockWarning()) { Warning out(_connection->communicator()->getLogger()); - out << "Deadlock in Freeze::MapHelperI::destroy on Map \"" + out << "Deadlock in Freeze::MapHelperI::destroy on Map \"" << _dbName << "\"; retrying ..."; } - + // // Ignored, try again // @@ -1575,7 +1652,6 @@ Freeze::MapHelperI::destroy() } } - size_t Freeze::MapHelperI::size() const { @@ -1604,7 +1680,6 @@ Freeze::MapHelperI::size() const return num; } - void Freeze::MapHelperI::closeAllIterators() { @@ -1657,8 +1732,6 @@ Freeze::MapHelperI::close() _indices.clear(); } - - void Freeze::MapHelperI::closeAllIteratorsExcept(const IteratorHelperI::TxPtr& tx) const { @@ -1680,12 +1753,11 @@ Freeze::MapHelperI::closeAllIteratorsExcept(const IteratorHelperI::TxPtr& tx) co } } - // // MapIndexI // -extern "C" +extern "C" { static int customIndexCompare(DB* db, const DBT* dbt1, const DBT* dbt2) { @@ -1713,10 +1785,10 @@ Freeze::MapIndexI::MapIndexI(const ConnectionIPtr& connection, MapDb& db, _index(index) { assert(txn != 0); - + _db.reset(new Db(connection->dbEnv()->getEnv(), 0)); _db->set_flags(DB_DUP | DB_DUPSORT); - + u_int32_t flags = 0; if(createDb) { @@ -1745,7 +1817,7 @@ Freeze::MapIndexI::MapIndexI(const ConnectionIPtr& connection, MapDb& db, _db->set_bt_minkey(btreeMinKey); } - + bool checksum = properties->getPropertyAsInt(propPrefix + "Checksum") > 0; if(checksum) { @@ -1757,7 +1829,7 @@ Freeze::MapIndexI::MapIndexI(const ConnectionIPtr& connection, MapDb& db, _db->set_flags(DB_CHKSUM); } - + int pageSize = properties->getPropertyAsInt(propPrefix + "PageSize"); if(pageSize > 0) { @@ -1769,7 +1841,7 @@ Freeze::MapIndexI::MapIndexI(const ConnectionIPtr& connection, MapDb& db, _db->set_pagesize(pageSize); } - + if(connection->trace() >= 1) { Trace out(connection->communicator()->getLogger(), "Freeze.Map"); @@ -1779,9 +1851,8 @@ Freeze::MapIndexI::MapIndexI(const ConnectionIPtr& connection, MapDb& db, // // Berkeley DB expects file paths to be UTF8 encoded. // - _db->open(txn, - IceUtil::nativeToUTF8(_dbName, IceUtil::getProcessStringConverter()).c_str(), - 0, DB_BTREE, flags, FREEZE_DB_MODE); + _db->open(txn, IceUtil::nativeToUTF8(_dbName, IceUtil::getProcessStringConverter()).c_str(), 0, DB_BTREE, flags, + FREEZE_DB_MODE); // // To populate empty indices @@ -1793,7 +1864,7 @@ Freeze::MapIndexI::MapIndexI(const ConnectionIPtr& connection, MapDb& db, // Note: caller catch and translates exceptions // } - + Freeze::MapIndexI::~MapIndexI() { try @@ -1806,8 +1877,7 @@ Freeze::MapIndexI::~MapIndexI() } } - -IteratorHelper* +IteratorHelper* Freeze::MapIndexI::begin(bool ro, const MapHelperI& m) const { IceUtil::UniquePtr<IteratorHelperI> r(new IteratorHelperI(m, ro, _index, false)); @@ -1822,9 +1892,8 @@ Freeze::MapIndexI::begin(bool ro, const MapHelperI& m) const } } -IteratorHelper* -Freeze::MapIndexI::untypedFind(const Key& k, bool ro, const MapHelperI& m, - bool onlyDups) const +IteratorHelper* +Freeze::MapIndexI::untypedFind(const Key& k, bool ro, const MapHelperI& m, bool onlyDups) const { IceUtil::UniquePtr<IteratorHelperI> r(new IteratorHelperI(m, ro, _index, onlyDups)); @@ -1838,7 +1907,7 @@ Freeze::MapIndexI::untypedFind(const Key& k, bool ro, const MapHelperI& m, } } -IteratorHelper* +IteratorHelper* Freeze::MapIndexI::untypedLowerBound(const Key& k, bool ro, const MapHelperI& m) const { IceUtil::UniquePtr<IteratorHelperI> r(new IteratorHelperI(m, ro, _index, false)); @@ -1853,7 +1922,7 @@ Freeze::MapIndexI::untypedLowerBound(const Key& k, bool ro, const MapHelperI& m) } } -IteratorHelper* +IteratorHelper* Freeze::MapIndexI::untypedUpperBound(const Key& k, bool ro, const MapHelperI& m) const { IceUtil::UniquePtr<IteratorHelperI> r(new IteratorHelperI(m, ro, _index, false)); @@ -1868,7 +1937,7 @@ Freeze::MapIndexI::untypedUpperBound(const Key& k, bool ro, const MapHelperI& m) } } -int +int Freeze::MapIndexI::untypedCount(const Key& k, const ConnectionIPtr& connection) const { Dbt dbKey; @@ -1890,12 +1959,11 @@ Freeze::MapIndexI::untypedCount(const Key& k, const ConnectionIPtr& connection) dbKey.set_ulen(static_cast<u_int32_t>(k.size())); #endif - Dbt dbValue; dbValue.set_flags(DB_DBT_USERMEM | DB_DBT_PARTIAL); int result = 0; - + DbTxn* txn = connection->dbTxn(); try @@ -1903,22 +1971,22 @@ Freeze::MapIndexI::untypedCount(const Key& k, const ConnectionIPtr& connection) for(;;) { Dbc* dbc = 0; - + try { // // Move to the first record - // + // _db->cursor(txn, &dbc, 0); bool found = (dbc->get(&dbKey, &dbValue, DB_SET) == 0); - + if(found) { db_recno_t count = 0; dbc->count(&count, 0); result = static_cast<int>(count); } - + Dbc* toClose = dbc; dbc = 0; toClose->close(); @@ -1950,7 +2018,7 @@ Freeze::MapIndexI::untypedCount(const Key& k, const ConnectionIPtr& connection) if(connection->deadlockWarning()) { Warning out(connection->communicator()->getLogger()); - out << "Deadlock in Freeze::MapIndexI::untypedCount while searching \"" + out << "Deadlock in Freeze::MapIndexI::untypedCount while searching \"" << _dbName << "\""; } @@ -1996,17 +2064,16 @@ Freeze::MapIndexI::untypedCount(const Key& k, const ConnectionIPtr& connection) { throw DatabaseException(__FILE__, __LINE__, dx.what()); } - + return result; } - + int -Freeze::MapIndexI::secondaryKeyCreate(Db* /*secondary*/, const Dbt* /*dbKey*/, - const Dbt* dbValue, Dbt* result) +Freeze::MapIndexI::secondaryKeyCreate(Db* /*secondary*/, const Dbt* /*dbKey*/, const Dbt* dbValue, Dbt* result) { Byte* first = static_cast<Byte*>(dbValue->get_data()); Value value(first, first + dbValue->get_size()); - + Key bytes; _index->marshalKey(value, bytes); diff --git a/cpp/src/Freeze/MapI.h b/cpp/src/Freeze/MapI.h index b648fb820e1..2883bd19bb9 100644 --- a/cpp/src/Freeze/MapI.h +++ b/cpp/src/Freeze/MapI.h @@ -13,7 +13,7 @@ #include <Freeze/Map.h> #include <Freeze/ConnectionI.h> #ifdef ICE_CPP11 -# include <memory> +# include <memory> #endif namespace Freeze @@ -22,38 +22,43 @@ namespace Freeze class MapDb; class MapHelperI; - class IteratorHelperI : public IteratorHelper -{ +{ public: IteratorHelperI(const MapHelperI& m, bool readOnly, const MapIndexBasePtr& index, bool onlyDups); IteratorHelperI(const IteratorHelperI&); - virtual + virtual ~IteratorHelperI() ICE_NOEXCEPT_FALSE; - - bool + + bool find(const Key& k) const; - bool + bool + find(const Dbt& k) const; + + bool lowerBound(const Key& k) const; - bool + bool upperBound(const Key& k) const; virtual IteratorHelper* clone() const; - + virtual const Key* get() const; virtual void get(const Key*&, const Value*&) const; - - virtual void + + virtual void set(const Value&); + virtual void + set(const Dbt&); + virtual void erase(); @@ -66,7 +71,7 @@ public: close(); class Tx -#ifndef ICE_CPP11 +#ifndef ICE_CPP11 : public IceUtil::SimpleShared #endif { @@ -110,14 +115,13 @@ private: mutable Key _key; mutable Value _value; -}; - +}; class MapHelperI : public MapHelper { public: - - MapHelperI(const ConnectionIPtr&, const std::string&, const std::string&, const std::string&, + + MapHelperI(const ConnectionIPtr&, const std::string&, const std::string&, const std::string&, const KeyCompareBasePtr&, const std::vector<MapIndexBasePtr>&, bool); virtual ~MapHelperI(); @@ -126,6 +130,9 @@ public: find(const Key&, bool) const; virtual IteratorHelper* + find(const Dbt&, bool) const; + + virtual IteratorHelper* lowerBound(const Key&, bool) const; virtual IteratorHelper* @@ -134,12 +141,21 @@ public: virtual void put(const Key&, const Value&); + virtual void + put(const Dbt&, const Dbt&); + virtual size_t erase(const Key&); virtual size_t + erase(const Dbt&); + + virtual size_t count(const Key&) const; - + + virtual size_t + count(const Dbt&) const; + virtual void clear(); @@ -157,7 +173,7 @@ public: virtual void closeDb(); - + virtual ConnectionPtr getConnection() const; @@ -169,9 +185,8 @@ public: return _connection; } - typedef std::map<std::string, MapIndexBasePtr> IndexMap; - + private: virtual void @@ -186,10 +201,9 @@ private: const std::string _dbName; IndexMap _indices; - Ice::Int _trace; + Ice::Int _trace; }; - inline const IteratorHelperI::TxPtr& IteratorHelperI::tx() const { diff --git a/cpp/src/Freeze/ObjectStore.cpp b/cpp/src/Freeze/ObjectStore.cpp index 1eaea6e2c92..b079086b2bb 100644 --- a/cpp/src/Freeze/ObjectStore.cpp +++ b/cpp/src/Freeze/ObjectStore.cpp @@ -22,7 +22,7 @@ using namespace Ice; using namespace Freeze; Freeze::ObjectStoreBase::ObjectStoreBase(const string& facet, const string& facetType, - bool createDb, EvictorIBase* evictor, + bool createDb, EvictorIBase* evictor, const vector<IndexPtr>& indices, bool populateEmptyIndices) : _facet(facet), @@ -51,13 +51,13 @@ Freeze::ObjectStoreBase::ObjectStoreBase(const string& facet, const string& face { throw DatabaseException(__FILE__, __LINE__, "No object factory registered for type-id '" + facetType + "'"); } - + _sampleServant = factory->create(facetType); } ConnectionPtr catalogConnection = createConnection(_communicator, evictor->dbEnv()->getEnvName()); Catalog catalog(catalogConnection, catalogName()); - + Catalog::iterator p = catalog.find(evictor->filename()); if(p != catalog.end()) { @@ -96,7 +96,7 @@ Freeze::ObjectStoreBase::ObjectStoreBase(const string& facet, const string& face _db->set_bt_minkey(btreeMinKey); } - + bool checksum = properties->getPropertyAsInt(propPrefix + "Checksum") > 0; if(checksum) { @@ -108,7 +108,7 @@ Freeze::ObjectStoreBase::ObjectStoreBase(const string& facet, const string& face _db->set_flags(DB_CHKSUM); } - + int pageSize = properties->getPropertyAsInt(propPrefix + "PageSize"); if(pageSize > 0) { @@ -120,7 +120,7 @@ Freeze::ObjectStoreBase::ObjectStoreBase(const string& facet, const string& face _db->set_pagesize(pageSize); } - + TransactionPtr tx = catalogConnection->beginTransaction(); DbTxn* txn = getTxn(tx); @@ -146,7 +146,7 @@ Freeze::ObjectStoreBase::ObjectStoreBase(const string& facet, const string& face { _indices[i]->_impl->associate(this, txn, createDb, populateEmptyIndices); } - + if(p == catalog.end()) { CatalogData catalogData; @@ -207,7 +207,7 @@ Freeze::ObjectStoreBase::~ObjectStoreBase() try { _db->close(0); - + for(size_t i = 0; i < _indices.size(); ++i) { try @@ -228,7 +228,7 @@ Freeze::ObjectStoreBase::~ObjectStoreBase() error << "Freeze: closing ObjectStore " << _dbName << " raised DbException: " << dx.what(); } } - + bool Freeze::ObjectStoreBase::dbHasObject(const Identity& ident, const TransactionIPtr& transaction) const { @@ -242,11 +242,10 @@ Freeze::ObjectStoreBase::dbHasObject(const Identity& ident, const TransactionIPt } } - Key key; - marshal(ident, key, _communicator, _encoding); Dbt dbKey; - initializeInDbt(key, dbKey); - + KeyMarshaler km(ident, _communicator, _encoding); + km.getDbt(dbKey); + // // Keep 0 length since we're not interested in the data // @@ -258,7 +257,7 @@ Freeze::ObjectStoreBase::dbHasObject(const Identity& ident, const TransactionIPt try { int err = _db->get(tx, &dbKey, &dbValue, 0); - + if(err == 0) { return true; @@ -278,7 +277,7 @@ Freeze::ObjectStoreBase::dbHasObject(const Identity& ident, const TransactionIPt if(_evictor->deadlockWarning()) { Warning out(_communicator->getLogger()); - out << "Deadlock in Freeze::ObjectStoreBase::dbHasObject while searching \"" + out << "Deadlock in Freeze::ObjectStoreBase::dbHasObject while searching \"" << _evictor->filename() + "/" + _dbName << "\"; retrying ..."; } @@ -299,19 +298,15 @@ Freeze::ObjectStoreBase::dbHasObject(const Identity& ident, const TransactionIPt } void -Freeze::ObjectStoreBase::save(Key& key, Value& value, Byte status, DbTxn* tx) +Freeze::ObjectStoreBase::save(Dbt& key, Dbt& value, Byte status, DbTxn* tx) { switch(status) { case created: case modified: { - Dbt dbKey; - Dbt dbValue; - initializeInDbt(key, dbKey); - initializeInDbt(value, dbValue); u_int32_t flags = (status == created) ? DB_NOOVERWRITE : 0; - int err = _db->put(tx, &dbKey, &dbValue, flags); + int err = _db->put(tx, &key, &value, flags); if(err != 0) { throw DatabaseException(__FILE__, __LINE__); @@ -321,15 +316,13 @@ Freeze::ObjectStoreBase::save(Key& key, Value& value, Byte status, DbTxn* tx) case destroyed: { - Dbt dbKey; - initializeInDbt(key, dbKey); - int err = _db->del(tx, &dbKey, 0); + int err = _db->del(tx, &key, 0); if(err != 0) { throw DatabaseException(__FILE__, __LINE__); } break; - } + } default: { assert(0); @@ -337,51 +330,55 @@ Freeze::ObjectStoreBase::save(Key& key, Value& value, Byte status, DbTxn* tx) } } -void -Freeze::ObjectStoreBase::marshal(const Identity& ident, - Key& bytes, - const CommunicatorPtr& communicator, - const EncodingVersion& encoding) +Freeze::ObjectStoreBase::Marshaler::Marshaler(const CommunicatorPtr& communicator, + const EncodingVersion& encoding) : + _os(IceInternal::getInstance(communicator).get(), encoding, true) { - IceInternal::InstancePtr instance = IceInternal::getInstance(communicator); - IceInternal::BasicStream stream(instance.get(), encoding, true); - stream.write(ident); - vector<Byte>(stream.b.begin(), stream.b.end()).swap(bytes); } - -void -Freeze::ObjectStoreBase::unmarshal(Identity& ident, - const Key& bytes, - const CommunicatorPtr& communicator, - const EncodingVersion& encoding) + +void +Freeze::ObjectStoreBase::Marshaler::getDbt(Dbt& dbt) const { - IceInternal::InstancePtr instance = IceInternal::getInstance(communicator); - IceInternal::BasicStream stream(instance.get(), encoding, &bytes[0], &bytes[0] + bytes.size()); - stream.read(ident); + initializeInDbt(const_cast<IceInternal::BasicStream&>(_os), dbt); } -void -Freeze::ObjectStoreBase::marshal(const ObjectRecord& v, - Value& bytes, - const CommunicatorPtr& communicator, - const EncodingVersion& encoding, - bool keepStats) +Freeze::ObjectStoreBase::KeyMarshaler::KeyMarshaler(const Identity& ident, + const CommunicatorPtr& communicator, + const EncodingVersion& encoding) : + Marshaler(communicator, encoding) { - IceInternal::InstancePtr instance = IceInternal::getInstance(communicator); - IceInternal::BasicStream stream(instance.get(), encoding, true); - stream.startWriteEncaps(); + _os.write(ident); +} + +Freeze::ObjectStoreBase::ValueMarshaler::ValueMarshaler(const ObjectRecord& rec, + const CommunicatorPtr& communicator, + const EncodingVersion& encoding, + bool keepStats) : + Marshaler(communicator, encoding) +{ + _os.startWriteEncaps(); if(keepStats) { - stream.write(v); + _os.write(rec); } else { - stream.write(v.servant); + _os.write(rec.servant); } - stream.writePendingObjects(); - stream.endWriteEncaps(); - vector<Byte>(stream.b.begin(), stream.b.end()).swap(bytes); + _os.writePendingObjects(); + _os.endWriteEncaps(); +} + +void +Freeze::ObjectStoreBase::unmarshal(Identity& ident, + const Key& bytes, + const CommunicatorPtr& communicator, + const EncodingVersion& encoding) +{ + IceInternal::InstancePtr instance = IceInternal::getInstance(communicator); + IceInternal::BasicStream stream(instance.get(), encoding, &bytes[0], &bytes[0] + bytes.size()); + stream.read(ident); } void @@ -395,7 +392,7 @@ Freeze::ObjectStoreBase::unmarshal(ObjectRecord& v, IceInternal::BasicStream stream(instance.get(), encoding, &bytes[0], &bytes[0] + bytes.size()); stream.sliceObjects(false); stream.startReadEncaps(); - + if(keepStats) { stream.read(v); @@ -404,7 +401,7 @@ Freeze::ObjectStoreBase::unmarshal(ObjectRecord& v, { stream.read(v.servant); } - + stream.readPendingObjects(); stream.endReadEncaps(); } @@ -418,17 +415,15 @@ Freeze::ObjectStoreBase::load(const Identity& ident, const TransactionIPtr& tran } DbTxn* txn = transaction->dbTxn(); - + if(txn == 0) { throw DatabaseException(__FILE__, __LINE__, "inactive transaction"); } - Key key; - marshal(ident, key, _communicator, _encoding); - Dbt dbKey; - initializeInDbt(key, dbKey); + KeyMarshaler km(ident, _communicator, _encoding); + km.getDbt(dbKey); const size_t defaultValueSize = 4096; Value value(defaultValueSize); @@ -457,7 +452,7 @@ Freeze::ObjectStoreBase::load(const Identity& ident, const TransactionIPtr& tran if(_evictor->deadlockWarning()) { Warning out(_communicator->getLogger()); - out << "Deadlock in Freeze::ObjectStoreBase::load while searching \"" + out << "Deadlock in Freeze::ObjectStoreBase::load while searching \"" << _evictor->filename() + "/" + _dbName << "\""; } throw DeadlockException(__FILE__, __LINE__, dx.what(), transaction); @@ -467,7 +462,7 @@ Freeze::ObjectStoreBase::load(const Identity& ident, const TransactionIPtr& tran handleDbException(dx, value, dbValue, __FILE__, __LINE__); } } - + unmarshal(rec, value, _communicator, _encoding, _keepStats); _evictor->initialize(ident, _facet, rec.servant); return true; @@ -482,22 +477,20 @@ Freeze::ObjectStoreBase::update(const Identity& ident, const ObjectRecord& rec, } DbTxn* txn = transaction->dbTxn(); - + if(txn == 0) { throw DatabaseException(__FILE__, __LINE__, "inactive transaction"); } - Key key; - marshal(ident, key, _communicator, _encoding); - - Value value; - marshal(rec, value, _communicator, _encoding, _keepStats); - Dbt dbKey; + KeyMarshaler km(ident, _communicator, _encoding); + km.getDbt(dbKey); + Dbt dbValue; - initializeInDbt(key, dbKey); - initializeInDbt(value, dbValue); + ValueMarshaler vm(rec, _communicator, _encoding, _keepStats); + vm.getDbt(dbValue); + u_int32_t flags = 0; try @@ -509,7 +502,7 @@ Freeze::ObjectStoreBase::update(const Identity& ident, const ObjectRecord& rec, if(_evictor->deadlockWarning()) { Warning out(_communicator->getLogger()); - out << "Deadlock in Freeze::ObjectStoreBase::update while updating \"" + out << "Deadlock in Freeze::ObjectStoreBase::update while updating \"" << _evictor->filename() + "/" + _dbName << "\""; } throw DeadlockException(__FILE__, __LINE__, dx.what(), transaction); @@ -533,16 +526,14 @@ Freeze::ObjectStoreBase::insert(const Identity& ident, const ObjectRecord& rec, } } - Key key; - marshal(ident, key, _communicator, _encoding); - - Value value; - marshal(rec, value, _communicator, _encoding, _keepStats); - Dbt dbKey; + KeyMarshaler km(ident, _communicator, _encoding); + km.getDbt(dbKey); + Dbt dbValue; - initializeInDbt(key, dbKey); - initializeInDbt(value, dbValue); + ValueMarshaler vm(rec, _communicator, _encoding, _keepStats); + vm.getDbt(dbValue); + u_int32_t flags = DB_NOOVERWRITE; if(tx == 0) { @@ -560,7 +551,7 @@ Freeze::ObjectStoreBase::insert(const Identity& ident, const ObjectRecord& rec, if(_evictor->deadlockWarning()) { Warning out(_communicator->getLogger()); - out << "Deadlock in Freeze::ObjectStoreBase::insert while updating \"" + out << "Deadlock in Freeze::ObjectStoreBase::insert while updating \"" << _evictor->filename() + "/" + _dbName << "\""; } if(tx != 0) @@ -591,11 +582,9 @@ Freeze::ObjectStoreBase::remove(const Identity& ident, const TransactionIPtr& tr } } - Key key; - marshal(ident, key, _communicator, _encoding); - Dbt dbKey; - initializeInDbt(key, dbKey); + KeyMarshaler km(ident, _communicator, _encoding); + km.getDbt(dbKey); for(;;) { @@ -608,7 +597,7 @@ Freeze::ObjectStoreBase::remove(const Identity& ident, const TransactionIPtr& tr if(_evictor->deadlockWarning()) { Warning out(_communicator->getLogger()); - out << "Deadlock in Freeze::ObjectStoreBase::remove while updating \"" + out << "Deadlock in Freeze::ObjectStoreBase::remove while updating \"" << _evictor->filename() + "/" + _dbName << "\""; } if(tx != 0) @@ -639,11 +628,9 @@ Freeze::ObjectStoreBase::dbName() const bool Freeze::ObjectStoreBase::loadImpl(const Identity& ident, ObjectRecord& rec) { - Key key; - marshal(ident, key, _communicator, _encoding); - Dbt dbKey; - initializeInDbt(key, dbKey); + KeyMarshaler km(ident, _communicator, _encoding); + km.getDbt(dbKey); const size_t defaultValueSize = 4096; Value value(defaultValueSize); @@ -672,7 +659,7 @@ Freeze::ObjectStoreBase::loadImpl(const Identity& ident, ObjectRecord& rec) if(_evictor->deadlockWarning()) { Warning out(_communicator->getLogger()); - out << "Deadlock in Freeze::ObjectStoreBase::load while searching \"" + out << "Deadlock in Freeze::ObjectStoreBase::load while searching \"" << _evictor->filename() + "/" + _dbName << "\"; retrying ..."; } // @@ -684,7 +671,7 @@ Freeze::ObjectStoreBase::loadImpl(const Identity& ident, ObjectRecord& rec) handleDbException(dx, value, dbValue, __FILE__, __LINE__); } } - + unmarshal(rec, value, _communicator, _encoding, _keepStats); _evictor->initialize(ident, _facet, rec.servant); return true; diff --git a/cpp/src/Freeze/ObjectStore.h b/cpp/src/Freeze/ObjectStore.h index 7c2cdea8e5b..8a73f68bbda 100644 --- a/cpp/src/Freeze/ObjectStore.h +++ b/cpp/src/Freeze/ObjectStore.h @@ -41,11 +41,40 @@ public: const Ice::ObjectPtr& sampleServant() const; bool dbHasObject(const Ice::Identity&, const TransactionIPtr&) const; - void save(Key& key, Value& value, Ice::Byte status, DbTxn* tx); + void save(Dbt&, Dbt&, Ice::Byte, DbTxn*); + + // + // This base class encapsulates a BasicStream, which allows us to avoid + // making any extra copies of marshaled data when updating the database. + // + class Marshaler + { + public: + + Marshaler(const Ice::CommunicatorPtr&, const Ice::EncodingVersion&); + + void getDbt(Dbt&) const; + + protected: + + IceInternal::BasicStream _os; + }; + + class KeyMarshaler : public Marshaler + { + public: + + KeyMarshaler(const Ice::Identity&, const Ice::CommunicatorPtr&, const Ice::EncodingVersion&); + }; + + class ValueMarshaler : public Marshaler + { + public: + + ValueMarshaler(const ObjectRecord&, const Ice::CommunicatorPtr&, const Ice::EncodingVersion&, bool); + }; - static void marshal(const Ice::Identity&, Key&, const Ice::CommunicatorPtr&, const Ice::EncodingVersion&); static void unmarshal(Ice::Identity&, const Key&, const Ice::CommunicatorPtr&, const Ice::EncodingVersion&); - static void marshal(const ObjectRecord&, Value&, const Ice::CommunicatorPtr&, const Ice::EncodingVersion&, bool); static void unmarshal(ObjectRecord&, const Value&, const Ice::CommunicatorPtr&, const Ice::EncodingVersion&, bool); bool load(const Ice::Identity&, const TransactionIPtr&, ObjectRecord&); diff --git a/cpp/src/Freeze/SharedDbEnv.cpp b/cpp/src/Freeze/SharedDbEnv.cpp index 85bd743c290..f3cbc70ae20 100644 --- a/cpp/src/Freeze/SharedDbEnv.cpp +++ b/cpp/src/Freeze/SharedDbEnv.cpp @@ -611,11 +611,10 @@ Freeze::SharedDbEnv::SharedDbEnv(const std::string& envName, // // Get catalogs // - _catalog = new MapDb(_communicator, _encoding, catalogName(), CatalogKeyCodec::typeId(), - CatalogValueCodec::typeId(), _env); + _catalog = new MapDb(_communicator, _encoding, catalogName(), Catalog::keyTypeId(), + Catalog::valueTypeId(), _env); _catalogIndexList = new MapDb(_communicator, _encoding, catalogIndexListName(), - CatalogIndexListKeyCodec::typeId(), CatalogIndexListValueCodec::typeId(), _env); - + CatalogIndexList::keyTypeId(), CatalogIndexList::valueTypeId(), _env); } catch(const ::DbException& dx) { diff --git a/cpp/src/Freeze/Util.h b/cpp/src/Freeze/Util.h index c5b243c1715..ef3deed6399 100644 --- a/cpp/src/Freeze/Util.h +++ b/cpp/src/Freeze/Util.h @@ -25,7 +25,7 @@ namespace Freeze { -inline void +inline void initializeInDbt(const std::vector<Ice::Byte>& v, Dbt& dbt) { dbt.set_data(const_cast<Ice::Byte*>(&v[0])); @@ -36,7 +36,18 @@ initializeInDbt(const std::vector<Ice::Byte>& v, Dbt& dbt) dbt.set_flags(DB_DBT_USERMEM); } -inline void +inline void +initializeInDbt(IceInternal::BasicStream& s, Dbt& dbt) +{ + dbt.set_data(const_cast<Ice::Byte*>(s.b.begin())); + dbt.set_size(static_cast<u_int32_t>(s.b.size())); + dbt.set_ulen(0); + dbt.set_dlen(0); + dbt.set_doff(0); + dbt.set_flags(DB_DBT_USERMEM); +} + +inline void initializeOutDbt(std::vector<Ice::Byte>& v, Dbt& dbt) { v.resize(v.capacity()); @@ -48,11 +59,22 @@ initializeOutDbt(std::vector<Ice::Byte>& v, Dbt& dbt) dbt.set_flags(DB_DBT_USERMEM); } +inline void +initializeOutDbt(IceInternal::BasicStream& s, Dbt& dbt) +{ + dbt.set_data(const_cast<Ice::Byte*>(s.b.begin())); + dbt.set_size(0); + dbt.set_ulen(static_cast<u_int32_t>(s.b.size())); + dbt.set_dlen(0); + dbt.set_doff(0); + dbt.set_flags(DB_DBT_USERMEM); +} + // -// Handles a Berkeley DB DbException by resizing the +// Handles a Berkeley DB DbException by resizing the // given key/value/dbt (when the exception's errno is -// DB_SMALL_BUFFER) or by throwing a +// DB_SMALL_BUFFER) or by throwing a // Freeze::DatabaseException // @@ -60,11 +82,11 @@ void handleDbException(const DbException&, const char*, int); void -handleDbException(const DbException&, Key&, Dbt&, +handleDbException(const DbException&, Key&, Dbt&, const char*, int); void -handleDbException(const DbException&, Key&, Dbt&, Value&, Dbt&, +handleDbException(const DbException&, Key&, Dbt&, Value&, Dbt&, const char*, int); } diff --git a/cpp/src/slice2freeze/Main.cpp b/cpp/src/slice2freeze/Main.cpp index 88c229fb52c..6b07ca47c86 100644 --- a/cpp/src/slice2freeze/Main.cpp +++ b/cpp/src/slice2freeze/Main.cpp @@ -139,7 +139,7 @@ private: _useWstring = _useWstringHist.back(); _useWstringHist.pop_back(); } - + bool _useWstring; std::list<bool> _useWstringHist; }; @@ -171,7 +171,7 @@ struct Dict StringList valueMetaData; bool sort; string userCompare; - + vector<DictIndex> indices; }; @@ -217,7 +217,7 @@ usage(const char* n) " Ice-encoding representation. Use 'sort' to sort\n" " with the COMPARE functor class. COMPARE's default\n" " value is std::less<KEY>\n" - "--index NAME,TYPE,MEMBER[,{case-sensitive|case-insensitive}]\n" + "--index NAME,TYPE,MEMBER[,{case-sensitive|case-insensitive}]\n" " Create a Freeze evictor index with the name\n" " NAME for member MEMBER of class TYPE. This\n" " option may be specified multiple times for\n" @@ -253,7 +253,7 @@ checkIdentifier(string t, string s) os << t << "' is not a valid type name"; throw os.str(); } - + for(unsigned int i = 1; i < s.size(); ++i) { if(!isalnum(static_cast<unsigned char>(s[i])) && s[i] != '_') @@ -272,13 +272,13 @@ printFreezeTypes(Output& out, const vector<Dict>& dicts, const vector<Index>& in out << "\n// Freeze types in this file:"; for(vector<Dict>::const_iterator p = dicts.begin(); p != dicts.end(); ++p) { - out << "\n// name=\"" << p->name << "\", key=\"" + out << "\n// name=\"" << p->name << "\", key=\"" << p->key << "\", value=\"" << p->value << "\""; } - + for(vector<Index>::const_iterator q = indices.begin(); q != indices.end(); ++q) { - out << "\n// name=\"" << q->name << "\", type=\"" << q->type + out << "\n// name=\"" << q->name << "\", type=\"" << q->type << "\", member=\"" << q->member << "\""; if(q->caseSensitive == false) { @@ -289,7 +289,7 @@ printFreezeTypes(Output& out, const vector<Dict>& dicts, const vector<Index>& in } template<class T> -inline string +inline string getCompare(const T& t, const string& keyType) { if(t.sort) @@ -309,125 +309,36 @@ getCompare(const T& t, const string& keyType) } } -void -writeCodecH(const TypePtr& type, const StringList& metaData, const string& name, const string& freezeType, Output& H, - const string& dllExport) -{ - H << sp << nl << "class " << dllExport << name; - H << sb; - H.dec(); - H << sp << nl << "public:"; - H << sp; - H.inc(); - H << nl << "static void write(" << inputTypeToString(type, false, metaData) - << ", Freeze::" << freezeType << "&, const ::Ice::CommunicatorPtr&, const Ice::EncodingVersion&);"; - H << nl << "static void read(" << typeToString(type, metaData) << "&, const Freeze::" << freezeType << "&, " - << "const ::Ice::CommunicatorPtr&, const Ice::EncodingVersion&);"; - H << nl << "static const std::string& typeId();"; - H << eb << ';'; -} - -void -writeCodecC(const TypePtr& type, const StringList& metaData, const string& name, const string& freezeType, bool encaps, - Output& C) +string +getTypeId(const TypePtr& type, const StringList& metaData) { - string quotedFreezeType = "\"" + freezeType + "\""; - - C << sp << nl << "void" << nl << name << "::write(" << inputTypeToString(type, false, metaData) << " v, " - << "Freeze::" << freezeType << "& bytes, const ::Ice::CommunicatorPtr& communicator, " - << "const Ice::EncodingVersion& encoding)"; - C << sb; - C << nl << "IceInternal::InstancePtr instance = IceInternal::getInstance(communicator);"; - C << nl << "IceInternal::BasicStream stream(instance.get(), encoding, true);"; - if(encaps) - { - C << nl << "stream.startWriteEncaps();"; - } - writeMarshalUnmarshalCode(C, type, false, 0, "v", true, metaData, 0, "stream", false); - if(type->usesClasses()) - { - C << nl << "stream.writePendingObjects();"; - } - if(encaps) - { - C << nl << "stream.endWriteEncaps();"; - } - C << nl << "::std::vector<Ice::Byte>(stream.b.begin(), stream.b.end()).swap(bytes);"; - C << eb; - - C << sp << nl << "void" << nl << name << "::read(" << typeToString(type, metaData) << "& v, " - << "const Freeze::" << freezeType << "& bytes, const ::Ice::CommunicatorPtr& communicator, " - << "const Ice::EncodingVersion& encoding)"; - C << sb; - C << nl << "IceInternal::InstancePtr instance = IceInternal::getInstance(communicator);"; - C << nl << "IceInternal::BasicStream stream(instance.get(), encoding, &bytes[0], &bytes[0] + bytes.size());"; - if(type->usesClasses()) - { - C << nl << "stream.sliceObjects(false);"; - } - if(encaps) - { - C << nl << "stream.startReadEncaps();"; - } - writeMarshalUnmarshalCode(C, type, false, 0, "v", false, metaData, 0, "stream", false); - if(type->usesClasses()) - { - C << nl << "stream.readPendingObjects();"; - } - if(encaps) - { - C << nl << "stream.endReadEncaps();"; - } - C << eb; - - string staticName = "__"; - for(string::const_iterator p = name.begin(); p != name.end(); ++p) - { - if((*p) == ':') - { - staticName += '_'; - } - else - { - staticName += *p; - } - } - staticName += "_typeId"; - string typeId = type->typeId(); BuiltinPtr builtInType = BuiltinPtr::dynamicCast(type); - if(builtInType && builtInType->kind() == Builtin::KindString && metaData.size() != 0 && + if(builtInType && builtInType->kind() == Builtin::KindString && metaData.size() != 0 && metaData.front() == "cpp:type:wstring") { typeId = "wstring"; } - C << sp << nl << "namespace"; - C << sb; - C << sp << nl << "const ::std::string " << staticName << " = \"" << typeId << "\";"; - C << eb; - - C << sp << nl << "const ::std::string&" << nl << name << "::typeId()"; - C << sb; - C << nl << "return " << staticName << ";"; - - C << eb; + return typeId; } void -writeDictWithIndicesH(const string& name, const Dict& dict, - const vector<IndexType> indexTypes, - const TypePtr& keyType, const StringList& keyMetaData, const TypePtr& valueType, - const StringList& valueMetaData, Output& H, const string& dllExport) +writeDictH(const string& name, const Dict& dict, const vector<IndexType> indexTypes, const TypePtr& keyType, + const StringList& keyMetaData, const TypePtr& valueType, const StringList& valueMetaData, Output& H, + const string& dllExport) { - string compare = getCompare(dict, typeToString(keyType, keyMetaData)); - - string templateParams = string("< ") + typeToString(keyType, keyMetaData) + ", " - + typeToString(valueType, valueMetaData) + ", " + name + "KeyCodec, " - + name + "ValueCodec, " + compare + " >"; + const string keyTypeS = typeToString(keyType, keyMetaData); + const string valueTypeS = typeToString(valueType, valueMetaData); + const string compare = getCompare(dict, keyTypeS); + const string keyCodec = string("::Freeze::MapKeyCodec< ") + keyTypeS + " >"; + const string valueCodec = + string(valueType->usesClasses() ? "::Freeze::MapObjectValueCodec" : "::Freeze::MapValueCodec") + + "< " + valueTypeS + " >"; + + const string templateParams = string("< ") + keyTypeS + ", " + valueTypeS + ", " + keyCodec + ", " + valueCodec + + ", " + compare + " >"; - string keyCompareParams = - string("< ") + typeToString(keyType, keyMetaData) + ", " - + name + "KeyCodec, " + compare + " >"; + const string keyCompareParams = string("< ") + keyTypeS + ", " + keyCodec + ", " + compare + " >"; vector<string> capitalizedMembers; @@ -446,7 +357,7 @@ writeDictWithIndicesH(const string& name, const Dict& dict, } } - H << sp << nl << "class " << dllExport << name + H << sp << nl << "class " << dllExport << name << " : public Freeze::Map" << templateParams; H << sb; H.dec(); @@ -458,8 +369,7 @@ writeDictWithIndicesH(const string& name, const Dict& dict, // Typedefs // /* - H << nl << "typedef std::pair<const " << typeToString(keyType, keyMetaData) - << ", const" << typeToString(valueType, valueMetaData) << "> value_type;"; + H << nl << "typedef std::pair<const " << keyTypeS << ", const " << valueTypeS << " > value_type;"; H << nl << "typedef Freeze::Iterator" << templateParams << " iterator;"; H << nl << "typedef Freeze::ConstIterator" << templateParams << " const_iterator;"; @@ -475,24 +385,22 @@ writeDictWithIndicesH(const string& name, const Dict& dict, { string className = capitalizedMembers[i] + "Index"; - string indexCompare = - getCompare(dict.indices[i], typeToString(indexTypes[i].type, indexTypes[i].metaData)); - - string indexCompareParams = - string("< ") + typeToString(indexTypes[i].type, indexTypes[i].metaData) + ", " + string indexCompare = getCompare(dict.indices[i], typeToString(indexTypes[i].type, indexTypes[i].metaData)); + + string indexCompareParams = string("< ") + typeToString(indexTypes[i].type, indexTypes[i].metaData) + ", " + className + ", " + indexCompare + " >"; H << sp << nl << "class " << dllExport << className - << " : public Freeze::MapIndex" << indexCompareParams; + << " : public Freeze::MapIndex" << indexCompareParams; H << sb; H.dec(); H << sp << nl << "public:"; H << sp; H.inc(); - H << nl << capitalizedMembers[i] << "Index(const std::string&, const " + H << nl << capitalizedMembers[i] << "Index(const std::string&, const " << indexCompare << "& = " << indexCompare << "());"; - + H << sp; // @@ -501,7 +409,7 @@ writeDictWithIndicesH(const string& name, const Dict& dict, H << nl << "static void write(" << inputTypeToString(indexTypes[i].type, 0, indexTypes[i].metaData) << ", Freeze::Key&, const Ice::CommunicatorPtr&, const Ice::EncodingVersion&);"; - H << nl << "static void read(" + H << nl << "static void read(" << typeToString(indexTypes[i].type, indexTypes[i].metaData) << "&, const Freeze::Key&, const ::Ice::CommunicatorPtr&, const Ice::EncodingVersion&);"; @@ -511,7 +419,7 @@ writeDictWithIndicesH(const string& name, const Dict& dict, H.inc(); H << nl << "virtual void marshalKey(const Freeze::Value&, Freeze::Key&) const;"; - + H << eb << ';'; } @@ -524,43 +432,55 @@ writeDictWithIndicesH(const string& name, const Dict& dict, H << sp; H << nl << "template <class _InputIterator>" << nl << name << "(const Freeze::ConnectionPtr& __connection, " - << "const std::string& __dbName, bool __createDb, " - << "_InputIterator __first, _InputIterator __last, " + << "const std::string& __dbName, bool __createDb, _InputIterator __first, _InputIterator __last, " << "const " << compare << "& __compare = " << compare << "())"; H.inc(); - H << nl << ": Freeze::Map" << templateParams <<"(__connection->getCommunicator(), __connection->getEncoding())"; - H.dec(); - H << sb; - H << nl << "Freeze::KeyCompareBasePtr __keyCompare = " - << "new Freeze::KeyCompare" << keyCompareParams << "(__compare, this->_communicator, this->_encoding);"; - H << nl << "std::vector<Freeze::MapIndexBasePtr> __indices;"; - for(size_t i = 0; i < capitalizedMembers.size(); ++i) + if(capitalizedMembers.empty()) { - string indexName = dict.indices[i].member; - if(indexName.empty()) + H << nl << ": Freeze::Map" << templateParams <<"(__connection, __dbName, keyTypeId(), valueTypeId(), " + << "__createDb, __first, __last, __compare)"; + H.dec(); + H << sb; + H << eb; + } + else + { + H << nl << ": Freeze::Map" << templateParams <<"(__connection->getCommunicator(), __connection->getEncoding())"; + H.dec(); + H << sb; + H << nl << "Freeze::KeyCompareBasePtr __keyCompare = " + << "new Freeze::KeyCompare" << keyCompareParams << "(__compare, this->_communicator, this->_encoding);"; + H << nl << "std::vector<Freeze::MapIndexBasePtr> __indices;"; + for(size_t i = 0; i < capitalizedMembers.size(); ++i) { - indexName = "index"; + string indexName = dict.indices[i].member; + if(indexName.empty()) + { + indexName = "index"; + } + indexName = string("\"") + indexName + "\""; + + H << nl << "__indices.push_back(new " << capitalizedMembers[i] << "Index(" << indexName << "));"; } - indexName = string("\"") + indexName + "\""; + H << nl << "this->_helper.reset(Freeze::MapHelper::create(__connection, __dbName, keyTypeId(), valueTypeId(), " + << "__keyCompare, __indices, __createDb));"; + H << nl << "while(__first != __last)"; + H << sb; + H << nl << "put(*__first);"; + H << nl << "++__first;"; + H << eb; + H << eb; - H << nl << "__indices.push_back(new " << capitalizedMembers[i] << "Index(" << indexName << "));"; + // + // Recreate + // + H << sp << nl << "static void recreate(const Freeze::ConnectionPtr&, const std::string&, " + << "const " << compare << "& = " << compare << "());"; } - H << nl << "this->_helper.reset(Freeze::MapHelper::create(__connection, __dbName, " - << name + "KeyCodec::typeId(), " - << name + "ValueCodec::typeId(), __keyCompare, __indices, __createDb));"; - H << nl << "while(__first != __last)"; - H << sb; - H << nl << "put(*__first);"; - H << nl << "++__first;"; - H << eb; - H << eb; - // - // Recreate - // - H << nl << "static void recreate(const Freeze::ConnectionPtr&, const std::string&, " - << "const " << compare << "& = " << compare << "());"; H << sp; + H << nl << "static std::string keyTypeId();"; + H << nl << "static std::string valueTypeId();"; // // Find, begin, lowerBound, upperBound, equalRange and count functions @@ -578,22 +498,22 @@ writeDictWithIndicesH(const string& name, const Dict& dict, H << nl << "iterator endFor" << capitalizedMembers[i] << "();"; H << nl << "const_iterator endFor" << capitalizedMembers[i] << "() const;"; - + H << nl << "iterator lowerBoundFor" << capitalizedMembers[i] << "(" << inputTypeToString(indexTypes[i].type, false, indexTypes[i].metaData) << ");"; H << nl << "const_iterator lowerBoundFor" << capitalizedMembers[i] << "(" << inputTypeToString(indexTypes[i].type, false, indexTypes[i].metaData) << ") const;"; - + H << nl << "iterator upperBoundFor" << capitalizedMembers[i] << "(" << inputTypeToString(indexTypes[i].type, false, indexTypes[i].metaData) << ");"; H << nl << "const_iterator upperBoundFor" << capitalizedMembers[i] << "(" << inputTypeToString(indexTypes[i].type, false, indexTypes[i].metaData) << ") const;"; - H << nl << "std::pair<iterator, iterator> equalRangeFor" - << capitalizedMembers[i] << "(" << inputTypeToString(indexTypes[i].type, false, indexTypes[i].metaData) + H << nl << "std::pair<iterator, iterator> equalRangeFor" + << capitalizedMembers[i] << "(" << inputTypeToString(indexTypes[i].type, false, indexTypes[i].metaData) << ");"; - - H << nl << "std::pair<const_iterator, const_iterator> equalRangeFor" + + H << nl << "std::pair<const_iterator, const_iterator> equalRangeFor" << capitalizedMembers[i] << "(" << inputTypeToString(indexTypes[i].type, false, indexTypes[i].metaData) << ") const;"; @@ -604,26 +524,30 @@ writeDictWithIndicesH(const string& name, const Dict& dict, << "(" << inputTypeToString(indexTypes[i].type, false, indexTypes[i].metaData) << ") const;"; } - + H << eb << ';'; } void -writeDictWithIndicesC(const string& name, const string& absolute, const Dict& dict, - const vector<IndexType> indexTypes, - const TypePtr& keyType, const StringList& keyMetaData, const TypePtr& valueType, - const StringList& valueMetaData, Output& C) -{ - string compare = getCompare(dict, typeToString(keyType, keyMetaData)); - - string templateParams = string("< ") + typeToString(keyType, keyMetaData) + ", " - + typeToString(valueType, valueMetaData) + ", " + name + "KeyCodec, " - + name + "ValueCodec, " + compare + " >"; - - string keyCompareParams = string("< ") + typeToString(keyType, keyMetaData) + ", " - + name + "KeyCodec, " + compare + " >"; - +writeDictC(const string& name, const string& absolute, const Dict& dict, const vector<IndexType> indexTypes, + const TypePtr& keyType, const StringList& keyMetaData, const TypePtr& valueType, + const StringList& valueMetaData, Output& C) +{ + const string keyTypeS = typeToString(keyType, keyMetaData); + const string valueTypeS = typeToString(valueType, valueMetaData); + const string compare = getCompare(dict, keyTypeS); + const string keyCodec = string("::Freeze::MapKeyCodec< ") + keyTypeS + " >"; + const string valueCodec = + string(valueType->usesClasses() ? "::Freeze::MapObjectValueCodec" : "::Freeze::MapValueCodec") + + "< " + valueTypeS + " >"; + + const string templateParams = string("< ") + keyTypeS + ", " + valueTypeS + ", " + keyCodec + ", " + valueCodec + + ", " + compare + " >"; + + const string keyCompareParams = string("< ") + keyTypeS + ", " + keyCodec + ", " + compare + " >"; + vector<string> capitalizedMembers; + for(size_t i = 0; i < dict.indices.size(); ++i) { const string& member = dict.indices[i].member; @@ -638,7 +562,6 @@ writeDictWithIndicesC(const string& name, const string& absolute, const Dict& di capitalizedMembers.push_back("Value"); } } - // // Nested index classes @@ -647,11 +570,9 @@ writeDictWithIndicesC(const string& name, const string& absolute, const Dict& di { string className = capitalizedMembers[i] + "Index"; - string indexCompare = - getCompare(dict.indices[i], typeToString(indexTypes[i].type, indexTypes[i].metaData)); + string indexCompare = getCompare(dict.indices[i], typeToString(indexTypes[i].type, indexTypes[i].metaData)); - string indexCompareParams = - string("< ") + typeToString(indexTypes[i].type, indexTypes[i].metaData) + ", " + string indexCompareParams = string("< ") + typeToString(indexTypes[i].type, indexTypes[i].metaData) + ", " + className + ", " + indexCompare + " >"; C << sp << nl << absolute << "::" << className << "::" << className @@ -659,17 +580,16 @@ writeDictWithIndicesC(const string& name, const string& absolute, const Dict& di << "const " << indexCompare << "& __compare)"; C.inc(); - C << nl << ": Freeze::MapIndex" - << indexCompareParams << "(__name, __compare)"; + C << nl << ": Freeze::MapIndex" << indexCompareParams << "(__name, __compare)"; C.dec(); C << sb; C << eb; - C << sp << nl << "void" - << nl << absolute << "::" << className << "::" + C << sp << nl << "void" + << nl << absolute << "::" << className << "::" << "marshalKey(const Freeze::Value& __v, Freeze::Key& __k) const"; C << sb; - + bool optimize = false; if(dict.indices[i].member.empty() && dict.indices[i].caseSensitive) @@ -682,10 +602,10 @@ writeDictWithIndicesC(const string& name, const string& absolute, const Dict& di // // Can't optimize // - C << nl << typeToString(valueType, valueMetaData) << " __x;"; - C << nl << absolute << "ValueCodec::read(__x, __v, _communicator, _encoding);"; + C << nl << valueTypeS << " __x;"; + C << nl << valueCodec << "::read(__x, __v, _communicator, _encoding);"; string param = "__x"; - + if(!dict.indices[i].member.empty()) { if(ClassDeclPtr::dynamicCast(valueType) != 0) @@ -700,17 +620,17 @@ writeDictWithIndicesC(const string& name, const string& absolute, const Dict& di C << nl << "write(" << param << ", __k, _communicator, _encoding);"; } C << eb; - - C << sp << nl << "void" - << nl << absolute << "::" << className << "::" + + C << sp << nl << "void" + << nl << absolute << "::" << className << "::" << "write(" << inputTypeToString(indexTypes[i].type, false, indexTypes[i].metaData) << " __index, Freeze::Key& __bytes, const Ice::CommunicatorPtr& __communicator, " << "const Ice::EncodingVersion& __encoding)"; C << sb; - + if(optimize) { - C << nl << absolute << "ValueCodec::write(__index, __bytes, __communicator, __encoding);"; + C << nl << valueCodec << "::write(__index, __bytes, __communicator, __encoding);"; } else { @@ -718,7 +638,7 @@ writeDictWithIndicesC(const string& name, const string& absolute, const Dict& di C << nl << "IceInternal::InstancePtr __instance = IceInternal::getInstance(__communicator);"; C << nl << "IceInternal::BasicStream __stream(__instance.get(), __encoding, true);"; - + string valueS; if(dict.indices[i].caseSensitive) { @@ -726,34 +646,34 @@ writeDictWithIndicesC(const string& name, const string& absolute, const Dict& di } else { - C << nl << typeToString(indexTypes[i].type, indexTypes[i].metaData) + C << nl << typeToString(indexTypes[i].type, indexTypes[i].metaData) << " __lowerCaseIndex = IceUtilInternal::toLower(__index);"; valueS = "__lowerCaseIndex"; } - - writeMarshalUnmarshalCode(C, indexTypes[i].type, false, 0, valueS, true, indexTypes[i].metaData, 0, + + writeMarshalUnmarshalCode(C, indexTypes[i].type, false, 0, valueS, true, indexTypes[i].metaData, 0, "__stream", false); C << nl << "::std::vector<Ice::Byte>(__stream.b.begin(), __stream.b.end()).swap(__bytes);"; } C << eb; - C << sp << nl << "void" - << nl << absolute << "::" << className << "::" + C << sp << nl << "void" + << nl << absolute << "::" << className << "::" << "read(" << typeToString(indexTypes[i].type, indexTypes[i].metaData) << "& __index, const Freeze::Key& __bytes, const Ice::CommunicatorPtr& __communicator, " << "const Ice::EncodingVersion& __encoding)"; C << sb; - + if(optimize) { - C << nl << absolute << "ValueCodec::read(__index, __bytes, __communicator, __encoding);"; + C << nl << valueCodec << "::read(__index, __bytes, __communicator, __encoding);"; } else { C << nl << "IceInternal::InstancePtr __instance = IceInternal::getInstance(__communicator);"; C << nl << "IceInternal::BasicStream __stream(__instance.get(), __encoding, "; C << "&__bytes[0], &__bytes[0] + __bytes.size());"; - + writeMarshalUnmarshalCode(C, indexTypes[i].type, false, 0, "__index", false, indexTypes[i].metaData, 0, "__stream", false); } @@ -766,64 +686,85 @@ writeDictWithIndicesC(const string& name, const string& absolute, const Dict& di C << sp << nl << absolute << "::" << name << "(const Freeze::ConnectionPtr& __connection, const std::string& __dbName ," << "bool __createDb, const " << compare << "& __compare)"; - C.inc(); - C << nl << ": Freeze::Map" << templateParams <<"(__connection->getCommunicator(), __connection->getEncoding())"; - C.dec(); - C << sb; - C << nl << "Freeze::KeyCompareBasePtr __keyCompare = " - << "new Freeze::KeyCompare" << keyCompareParams << "(__compare, _communicator, _encoding);"; - C << nl << "std::vector<Freeze::MapIndexBasePtr> __indices;"; - for(size_t i = 0; i < capitalizedMembers.size(); ++i) + if(capitalizedMembers.empty()) { - string indexName = dict.indices[i].member; - if(indexName.empty()) - { - indexName = "index"; - } - indexName = string("\"") + indexName + "\""; - - C << nl << "__indices.push_back(new " << capitalizedMembers[i] << "Index(" << indexName << "));"; + C.inc(); + C << nl << ": Freeze::Map" << templateParams + <<"(__connection, __dbName, keyTypeId(), valueTypeId(), __createDb, __compare)"; + C.dec(); + C << sb; + C << eb; } - C << nl << "_helper.reset(Freeze::MapHelper::create(__connection, __dbName, " - << absolute + "KeyCodec::typeId(), " - << absolute + "ValueCodec::typeId(), __keyCompare, __indices, __createDb));"; - C << eb; - - // - // Recreate - // - C << sp << nl << "void" - << nl << absolute - << "::recreate(const Freeze::ConnectionPtr& __connection, const std::string& __dbName ," - << " const " << compare << "& __compare)"; - C << sb; - C << nl << "Freeze::KeyCompareBasePtr __keyCompare = " - << "new Freeze::KeyCompare" << keyCompareParams << "(__compare, __connection->getCommunicator()" - <<", __connection->getEncoding());"; - C << nl << "std::vector<Freeze::MapIndexBasePtr> __indices;"; - for(size_t i = 0; i < capitalizedMembers.size(); ++i) + else { - string indexName = dict.indices[i].member; - if(indexName.empty()) + C.inc(); + C << nl << ": Freeze::Map" << templateParams <<"(__connection->getCommunicator(), __connection->getEncoding())"; + C.dec(); + C << sb; + C << nl << "Freeze::KeyCompareBasePtr __keyCompare = " + << "new Freeze::KeyCompare" << keyCompareParams << "(__compare, _communicator, _encoding);"; + C << nl << "std::vector<Freeze::MapIndexBasePtr> __indices;"; + for(size_t i = 0; i < capitalizedMembers.size(); ++i) { - indexName = "index"; + string indexName = dict.indices[i].member; + if(indexName.empty()) + { + indexName = "index"; + } + indexName = string("\"") + indexName + "\""; + + C << nl << "__indices.push_back(new " << capitalizedMembers[i] << "Index(" << indexName << "));"; } - indexName = string("\"") + indexName + "\""; + C << nl << "_helper.reset(Freeze::MapHelper::create(__connection, __dbName, keyTypeId(), valueTypeId(), " + << "__keyCompare, __indices, __createDb));"; + C << eb; + + // + // Recreate + // + C << sp << nl << "void" + << nl << absolute + << "::recreate(const Freeze::ConnectionPtr& __connection, const std::string& __dbName ," + << " const " << compare << "& __compare)"; + C << sb; + C << nl << "Freeze::KeyCompareBasePtr __keyCompare = " + << "new Freeze::KeyCompare" << keyCompareParams << "(__compare, __connection->getCommunicator()" + <<", __connection->getEncoding());"; + C << nl << "std::vector<Freeze::MapIndexBasePtr> __indices;"; + for(size_t i = 0; i < capitalizedMembers.size(); ++i) + { + string indexName = dict.indices[i].member; + if(indexName.empty()) + { + indexName = "index"; + } + indexName = string("\"") + indexName + "\""; - C << nl << "__indices.push_back(new " << capitalizedMembers[i] << "Index(" << indexName << "));"; + C << nl << "__indices.push_back(new " << capitalizedMembers[i] << "Index(" << indexName << "));"; + } + C << nl << "Freeze::MapHelper::recreate(__connection, __dbName, keyTypeId(), valueTypeId(), __keyCompare, " + << "__indices);"; + C << eb; } - C << nl << "Freeze::MapHelper::recreate(__connection, __dbName, " - << absolute + "KeyCodec::typeId(), " - << absolute + "ValueCodec::typeId(), __keyCompare, __indices);"; + + C << sp << nl << "std::string" + << nl << absolute << "::keyTypeId()"; + C << sb; + C << nl << "return \"" << getTypeId(keyType, keyMetaData) << "\";"; + C << eb; + C << sp << nl << "std::string" + << nl << absolute << "::valueTypeId()"; + C << sb; + C << nl << "return \"" << getTypeId(valueType, valueMetaData) << "\";"; C << eb; // // Find and count functions // for(size_t i = 0; i < capitalizedMembers.size(); ++i) - { + { string indexClassName = capitalizedMembers[i] + "Index"; - + string indexName = dict.indices[i].member; if(indexName.empty()) { @@ -838,7 +779,7 @@ writeDictWithIndicesC(const string& name, const string& absolute, const Dict& di C << sb; C << nl << "Freeze::Key __bytes;"; C << nl << indexClassName << "::" << "write(__index, __bytes, _communicator, _encoding);"; - C << nl << "return iterator(_helper->index(" << indexName + C << nl << "return iterator(_helper->index(" << indexName << ")->untypedFind(__bytes, false, __onlyDups), _communicator, _encoding);"; C << eb; @@ -849,7 +790,7 @@ writeDictWithIndicesC(const string& name, const string& absolute, const Dict& di C << sb; C << nl << "Freeze::Key __bytes;"; C << nl << indexClassName << "::" << "write(__index, __bytes, _communicator, _encoding);"; - C << nl << "return const_iterator(_helper->index(" << indexName + C << nl << "return const_iterator(_helper->index(" << indexName << ")->untypedFind(__bytes, true, __onlyDups), _communicator, _encoding);"; C << eb; @@ -883,7 +824,7 @@ writeDictWithIndicesC(const string& name, const string& absolute, const Dict& di C << sb; C << nl << "Freeze::Key __bytes;"; C << nl << indexClassName << "::" << "write(__index, __bytes, _communicator, _encoding);"; - C << nl << "return iterator(_helper->index(" << indexName + C << nl << "return iterator(_helper->index(" << indexName << ")->untypedLowerBound(__bytes, false), _communicator, _encoding);"; C << eb; @@ -893,17 +834,17 @@ writeDictWithIndicesC(const string& name, const string& absolute, const Dict& di C << sb; C << nl << "Freeze::Key __bytes;"; C << nl << indexClassName << "::" << "write(__index, __bytes, _communicator, _encoding);"; - C << nl << "return const_iterator(_helper->index(" << indexName + C << nl << "return const_iterator(_helper->index(" << indexName << ")->untypedLowerBound(__bytes, true), _communicator, _encoding);"; C << eb; - + C << sp << nl << absolute << "::iterator" << nl << absolute << "::" << "upperBoundFor" << capitalizedMembers[i] << "(" << inputTypeToString(indexTypes[i].type, false, indexTypes[i].metaData) << " __index)"; C << sb; C << nl << "Freeze::Key __bytes;"; C << nl << indexClassName << "::" << "write(__index, __bytes, _communicator, _encoding);"; - C << nl << "return iterator(_helper->index(" << indexName + C << nl << "return iterator(_helper->index(" << indexName << ")->untypedUpperBound(__bytes, false), _communicator, _encoding);"; C << eb; @@ -913,10 +854,10 @@ writeDictWithIndicesC(const string& name, const string& absolute, const Dict& di C << sb; C << nl << "Freeze::Key __bytes;"; C << nl << indexClassName << "::" << "write(__index, __bytes, _communicator, _encoding);"; - C << nl << "return const_iterator(_helper->index(" << indexName + C << nl << "return const_iterator(_helper->index(" << indexName << ")->untypedUpperBound(__bytes, true), _communicator, _encoding);"; C << eb; - + C << sp << nl << "std::pair<" << absolute << "::iterator, " << absolute << "::iterator>" << nl << absolute << "::" << "equalRangeFor" << capitalizedMembers[i] @@ -935,7 +876,7 @@ writeDictWithIndicesC(const string& name, const string& absolute, const Dict& di << "(__index), upperBoundFor" << capitalizedMembers[i] << "(__index));"; C << eb; - string countFunction = dict.indices[i].member.empty() ? string("valueCount") + string countFunction = dict.indices[i].member.empty() ? string("valueCount") : dict.indices[i].member + "Count"; C << sp << nl << "int" @@ -944,7 +885,7 @@ writeDictWithIndicesC(const string& name, const string& absolute, const Dict& di C << sb; C << nl << "Freeze::Key __bytes;"; C << nl << indexClassName << "::" << "write(__index, __bytes, _communicator, _encoding);"; - C << nl << "return _helper->index(" << indexName + C << nl << "return _helper->index(" << indexName << ")->untypedCount(__bytes);"; C << eb; } @@ -965,12 +906,12 @@ writeDict(const string& n, const UnitPtr& u, const Dict& dict, Output& H, Output { string s = name.substr(0, pos); name.erase(0, pos + 2); - + checkIdentifier(absolute, s); - + scope.push_back(s); } - + checkIdentifier(absolute, name); TypeList keyTypes = u->lookupType(dict.key, false); @@ -981,7 +922,7 @@ writeDict(const string& n, const UnitPtr& u, const Dict& dict, Output& H, Output throw os.str(); } TypePtr keyType = keyTypes.front(); - + TypeList valueTypes = u->lookupType(dict.value, false); if(valueTypes.empty()) { @@ -990,153 +931,136 @@ writeDict(const string& n, const UnitPtr& u, const Dict& dict, Output& H, Output throw os.str(); } TypePtr valueType = valueTypes.front(); - + for(vector<string>::const_iterator q = scope.begin(); q != scope.end(); ++q) { H << sp; H << nl << "namespace " << *q << nl << '{'; } - writeCodecH(keyType, dict.keyMetaData, name + "KeyCodec", "Key", H, dllExport); - writeCodecH(valueType, dict.valueMetaData, name + "ValueCodec", "Value", H, dllExport); - vector<IndexType> indexTypes; - if(dict.indices.size() == 0) + for(vector<DictIndex>::const_iterator p = dict.indices.begin(); p != dict.indices.end(); ++p) { - string compare = getCompare(dict, typeToString(keyType, dict.keyMetaData)); - - H << sp << nl << "typedef Freeze::Map< " << typeToString(keyType, dict.keyMetaData) - << ", " << typeToString(valueType, dict.valueMetaData) << ", " - << name << "KeyCodec, " << name << "ValueCodec, " << compare - << " > " << name << ";"; - } - else - { - for(vector<DictIndex>::const_iterator p = dict.indices.begin(); - p != dict.indices.end(); ++p) + const DictIndex& index = *p; + if(index.member.empty()) { - const DictIndex& index = *p; - if(index.member.empty()) + if(dict.indices.size() > 1) + { + ostringstream os; + os << "bad index for dictionary `" << dict.name << "'"; + throw os.str(); + } + + bool containsSequence = false; + if(!Dictionary::legalKeyType(valueType, containsSequence)) { - if(dict.indices.size() > 1) + ostringstream os; + os << "`" << dict.value << "' is not a valid index type"; + throw os.str(); + } + if(containsSequence) + { + getErrorStream() << n << ": warning: use of sequences in dictionary keys has been deprecated"; + } + + if(index.caseSensitive == false) + { + // + // Let's check value is a string + // + + BuiltinPtr builtInType = BuiltinPtr::dynamicCast(valueType); + + if(builtInType == 0 || builtInType->kind() != Builtin::KindString) { ostringstream os; - os << "bad index for dictionary `" << dict.name << "'"; + os << "VALUE is a `" << dict.value << "', not a string"; throw os.str(); } - - bool containsSequence = false; - if(!Dictionary::legalKeyType(valueType, containsSequence)) + } + IndexType iType; + iType.type = valueType; + iType.metaData = dict.valueMetaData; + indexTypes.push_back(iType); + } + else + { + DataMemberPtr dataMember = 0; + DataMemberList dataMembers; + + ClassDeclPtr classDecl = ClassDeclPtr::dynamicCast(valueType); + if(classDecl != 0) + { + dataMembers = classDecl->definition()->allDataMembers(); + } + else + { + StructPtr structDecl = StructPtr::dynamicCast(valueType); + if(structDecl == 0) { ostringstream os; - os << "`" << dict.value << "' is not a valid index type"; + os << "`" << dict.value << "' is neither a class nor a struct."; throw os.str(); } - if(containsSequence) - { - getErrorStream() << n << ": warning: use of sequences in dictionary keys has been deprecated"; - } - - if(index.caseSensitive == false) - { - // - // Let's check value is a string - // - - BuiltinPtr builtInType = BuiltinPtr::dynamicCast(valueType); - - if(builtInType == 0 || builtInType->kind() != Builtin::KindString) - { - ostringstream os; - os << "VALUE is a `" << dict.value << "', not a string"; - throw os.str(); - } - } - IndexType iType; - iType.type = valueType; - iType.metaData = dict.valueMetaData; - indexTypes.push_back(iType); + dataMembers = structDecl->dataMembers(); } - else + DataMemberList::const_iterator d = dataMembers.begin(); + while(d != dataMembers.end() && dataMember == 0) { - DataMemberPtr dataMember = 0; - DataMemberList dataMembers; - - ClassDeclPtr classDecl = ClassDeclPtr::dynamicCast(valueType); - if(classDecl != 0) + if((*d)->name() == index.member) { - dataMembers = classDecl->definition()->allDataMembers(); + dataMember = *d; } else { - StructPtr structDecl = StructPtr::dynamicCast(valueType); - if(structDecl == 0) - { - ostringstream os; - os << "`" << dict.value << "' is neither a class nor a struct."; - throw os.str(); - } - dataMembers = structDecl->dataMembers(); - } - DataMemberList::const_iterator d = dataMembers.begin(); - while(d != dataMembers.end() && dataMember == 0) - { - if((*d)->name() == index.member) - { - dataMember = *d; - } - else - { - ++d; - } - } - - if(dataMember == 0) - { - ostringstream os; - os << "The value of `" << dict.name - << "' has no data member named `" << index.member << "'"; - throw os.str(); + ++d; } - - TypePtr dataMemberType = dataMember->type(); + } + + if(dataMember == 0) + { + ostringstream os; + os << "The value of `" << dict.name + << "' has no data member named `" << index.member << "'"; + throw os.str(); + } - bool containsSequence = false; - if(!Dictionary::legalKeyType(dataMemberType, containsSequence)) + TypePtr dataMemberType = dataMember->type(); + + bool containsSequence = false; + if(!Dictionary::legalKeyType(dataMemberType, containsSequence)) + { + ostringstream os; + os << "`" << index.member << "' cannot be used as an index"; + throw os.str(); + } + if(containsSequence) + { + getErrorStream() << n << ": warning: use of sequences in dictionary keys has been deprecated"; + } + + if(index.caseSensitive == false) + { + // + // Let's check member is a string + // + BuiltinPtr memberType = BuiltinPtr::dynamicCast(dataMemberType); + if(memberType == 0 || memberType->kind() != Builtin::KindString) { ostringstream os; - os << "`" << index.member << "' cannot be used as an index"; + os << "`" << index.member << "' is not a string "; throw os.str(); } - if(containsSequence) - { - getErrorStream() << n << ": warning: use of sequences in dictionary keys has been deprecated"; - } - - if(index.caseSensitive == false) - { - // - // Let's check member is a string - // - BuiltinPtr memberType = BuiltinPtr::dynamicCast(dataMemberType); - if(memberType == 0 || memberType->kind() != Builtin::KindString) - { - ostringstream os; - os << "`" << index.member << "' is not a string "; - throw os.str(); - } - } - IndexType iType; - iType.type = dataMemberType; - iType.metaData = dataMember->getMetaData(); - indexTypes.push_back(iType); } + IndexType iType; + iType.type = dataMemberType; + iType.metaData = dataMember->getMetaData(); + indexTypes.push_back(iType); } - writeDictWithIndicesH(name, dict, indexTypes, keyType, dict.keyMetaData, valueType, dict.valueMetaData, H, - dllExport); } + writeDictH(name, dict, indexTypes, keyType, dict.keyMetaData, valueType, dict.valueMetaData, H, dllExport); for(vector<string>::const_iterator q = scope.begin(); q != scope.end(); ++q) { @@ -1144,14 +1068,7 @@ writeDict(const string& n, const UnitPtr& u, const Dict& dict, Output& H, Output H << nl << '}'; } - writeCodecC(keyType, dict.keyMetaData, absolute + "KeyCodec", "Key", false, C); - writeCodecC(valueType, dict.valueMetaData, absolute + "ValueCodec", "Value", true, C); - - if(indexTypes.size() > 0) - { - writeDictWithIndicesC(name, absolute, dict, indexTypes, keyType, dict.keyMetaData, valueType, - dict.valueMetaData, C); - } + writeDictC(name, absolute, dict, indexTypes, keyType, dict.keyMetaData, valueType, dict.valueMetaData, C); } void @@ -1164,7 +1081,7 @@ writeIndexH(const string& memberTypeString, const string& name, Output& H, const H << sp << nl << "public:"; H << sp; H.inc(); - + H << nl << name << "(const std::string&, const std::string& = \"\");"; H << sp << nl << "std::vector<Ice::Identity>"; H << nl << "findFirst(" << memberTypeString << ", Ice::Int) const;"; @@ -1178,13 +1095,13 @@ writeIndexH(const string& memberTypeString, const string& name, Output& H, const H << sp << nl << "private:"; H << sp; H.inc(); - + H << nl << "virtual bool"; H << nl << "marshalKey(const Ice::ObjectPtr&, Freeze::Key&) const;"; - + H << sp << nl << "void"; H << nl << "marshalKey(" << memberTypeString << ", Freeze::Key&) const;"; - + H << eb << ';'; H << sp; H << nl << "typedef IceUtil::Handle<" << name << "> " << name << "Ptr;"; @@ -1196,7 +1113,7 @@ writeIndexC(const TypePtr& type, const TypePtr& memberType, const string& member { string inputType = inputTypeToString(memberType, false); - C << sp << nl << fullName << "::" << name + C << sp << nl << fullName << "::" << name << "(const ::std::string& __name, const ::std::string& __facet)"; C.inc(); C << nl << ": Freeze::Index(__name, __facet)"; @@ -1229,7 +1146,7 @@ writeIndexC(const TypePtr& type, const TypePtr& memberType, const string& member C << eb; string typeString = typeToString(type); - + C << sp << nl << "bool"; C << nl << fullName << "::" << "marshalKey(const Ice::ObjectPtr& __servant, Freeze::Key& __bytes) const"; C << sb; @@ -1244,13 +1161,13 @@ writeIndexC(const TypePtr& type, const TypePtr& memberType, const string& member C << nl << "return false;"; C << eb; C << eb; - + C << sp << nl << "void"; C << nl << fullName << "::" << "marshalKey(" << inputType << " __index, Freeze::Key& __bytes) const"; C << sb; C << nl << "IceInternal::InstancePtr __instance = IceInternal::getInstance(_communicator);"; C << nl << "IceInternal::BasicStream __stream(__instance.get(), _encoding, true);"; - + string valueS; if(caseSensitive) { @@ -1286,12 +1203,12 @@ writeIndex(const string& /*n*/, const UnitPtr& u, const Index& index, Output& H, { string s = name.substr(0, pos); name.erase(0, pos + 2); - + checkIdentifier(absolute, s); - + scope.push_back(s); } - + checkIdentifier(absolute, name); TypeList types = u->lookupType(index.type, false); @@ -1302,7 +1219,7 @@ writeIndex(const string& /*n*/, const UnitPtr& u, const Index& index, Output& H, throw os.str(); } TypePtr type = types.front(); - + ClassDeclPtr classDecl = ClassDeclPtr::dynamicCast(type); if(classDecl == 0) { @@ -1332,7 +1249,7 @@ writeIndex(const string& /*n*/, const UnitPtr& u, const Index& index, Output& H, os << "`" << index.type << "' has no data member named `" << index.member << "'"; throw os.str(); } - + if(index.caseSensitive == false) { // @@ -1346,7 +1263,7 @@ writeIndex(const string& /*n*/, const UnitPtr& u, const Index& index, Output& H, throw os.str(); } } - + for(vector<string>::const_iterator q = scope.begin(); q != scope.end(); ++q) { H << sp; @@ -1354,7 +1271,7 @@ writeIndex(const string& /*n*/, const UnitPtr& u, const Index& index, Output& H, } writeIndexH(inputTypeToString(dataMember->type(), false), name, H, dllExport); - + for(vector<string>::const_iterator q = scope.begin(); q != scope.end(); ++q) { H << sp; @@ -1486,7 +1403,7 @@ gen(const string& name, const UnitPtr& u, const vector<string>& includePaths, co for(vector<Dict>::const_iterator p = dicts.begin(); p != dicts.end(); ++p) { writeDict(name, u, *p, H, CPP, dllExport); - } + } for(vector<Index>::const_iterator q = indices.begin(); q != indices.end(); ++q) { @@ -1522,7 +1439,7 @@ compile(int argc, char* argv[]) opts.addOpt("d", "debug"); opts.addOpt("", "ice"); opts.addOpt("", "underscore"); - + vector<string> args; try { @@ -1588,7 +1505,7 @@ compile(int argc, char* argv[]) for(vector<string>::const_iterator i = optargs.begin(); i != optargs.end(); ++i) { string s = IceUtilInternal::removeWhitespace(*i); - + Dict dict; string::size_type pos; @@ -1714,13 +1631,13 @@ compile(int argc, char* argv[]) dicts.push_back(dict); } - + vector<Index> indices; optargs = opts.argVec("index"); for(vector<string>::const_iterator i = optargs.begin(); i != optargs.end(); ++i) { string s = IceUtilInternal::removeWhitespace(*i); - + Index index; string::size_type pos; @@ -1770,7 +1687,7 @@ compile(int argc, char* argv[]) usage(argv[0]); return EXIT_FAILURE; } - + if(caseString != "case-sensitive" && caseString != "case-insensitive") { getErrorStream() << argv[0] << ": error: " << *i << ": the case can be `case-sensitive' or " @@ -1787,7 +1704,7 @@ compile(int argc, char* argv[]) for(vector<string>::const_iterator i = optargs.begin(); i != optargs.end(); ++i) { string s = IceUtilInternal::removeWhitespace(*i); - + string dictName; DictIndex index; index.sort = false; @@ -1844,7 +1761,7 @@ compile(int argc, char* argv[]) { string subs = s.substr(0, pos); s.erase(0, pos + 1); - + if(subs == "sort") { index.sort = true; @@ -1879,7 +1796,7 @@ compile(int argc, char* argv[]) } } } - + if(dictName.empty()) { getErrorStream() << argv[0] << ": error: " << *i << ": no dictionary specified" << endl; @@ -1894,7 +1811,7 @@ compile(int argc, char* argv[]) { if(find(p->indices.begin(), p->indices.end(), index) != p->indices.end()) { - getErrorStream() << argv[0] << ": error: --dict-index " << *i + getErrorStream() << argv[0] << ": error: --dict-index " << *i << ": this dict-index is defined twice" << endl; return EXIT_FAILURE; } @@ -1983,7 +1900,7 @@ compile(int argc, char* argv[]) if(!icecpp->close()) { u->destroy(); - return EXIT_FAILURE; + return EXIT_FAILURE; } { @@ -2030,7 +1947,7 @@ compile(int argc, char* argv[]) return EXIT_FAILURE; } } - + u->destroy(); { |