diff options
author | Matthew Newhook <matthew@zeroc.com> | 2001-12-05 19:44:24 +0000 |
---|---|---|
committer | Matthew Newhook <matthew@zeroc.com> | 2001-12-05 19:44:24 +0000 |
commit | e4418f42b61488dd93424f467757acc985c4fce8 (patch) | |
tree | 9acd35f169de1912920954acf13af8e940ded959 /cpp | |
parent | fixes (diff) | |
download | ice-e4418f42b61488dd93424f467757acc985c4fce8.tar.bz2 ice-e4418f42b61488dd93424f467757acc985c4fce8.tar.xz ice-e4418f42b61488dd93424f467757acc985c4fce8.zip |
Freeze::DBMap updates. Removed DBWrapper, operator[]. Added set method to
the iterator.
Diffstat (limited to 'cpp')
-rw-r--r-- | cpp/demo/Freeze/phonebook/Collocated.cpp | 2 | ||||
-rw-r--r-- | cpp/demo/Freeze/phonebook/PhoneBookI.cpp | 33 | ||||
-rw-r--r-- | cpp/demo/Freeze/phonebook/Server.cpp | 2 | ||||
-rw-r--r-- | cpp/include/Freeze/Map.h | 286 | ||||
-rw-r--r-- | cpp/slice/Freeze/DB.ice | 14 | ||||
-rw-r--r-- | cpp/src/Freeze/DBI.cpp | 33 | ||||
-rw-r--r-- | cpp/src/Freeze/DBI.h | 1 | ||||
-rw-r--r-- | cpp/src/Freeze/EvictorI.cpp | 8 | ||||
-rw-r--r-- | cpp/test/Freeze/dbmap/Client.cpp | 39 |
9 files changed, 164 insertions, 254 deletions
diff --git a/cpp/demo/Freeze/phonebook/Collocated.cpp b/cpp/demo/Freeze/phonebook/Collocated.cpp index 54ba46a4245..8bc09ff765b 100644 --- a/cpp/demo/Freeze/phonebook/Collocated.cpp +++ b/cpp/demo/Freeze/phonebook/Collocated.cpp @@ -77,7 +77,7 @@ PhoneBookCollocated::runFreeze(int argc, char* argv[], const DBEnvironmentPtr& d // Create the phonebook, and add it to the Object Adapter. // PhoneBookIPtr phoneBook = new PhoneBookI(adapter, dbPhoneBook, evictor); - adapter->add(phoneBook, "phonebook"); + adapter->add(phoneBook, Ice::stringToIdentity("phonebook")); // // Create and install a factory and initializer for contacts. diff --git a/cpp/demo/Freeze/phonebook/PhoneBookI.cpp b/cpp/demo/Freeze/phonebook/PhoneBookI.cpp index 94ae406d5b4..d19fd0f8807 100644 --- a/cpp/demo/Freeze/phonebook/PhoneBookI.cpp +++ b/cpp/demo/Freeze/phonebook/PhoneBookI.cpp @@ -133,10 +133,15 @@ PhoneBookI::createContact(const Ice::Current&) // is the empty string. See the comment in getNewIdentity why the // prefix "N" is needed. // + NameIdentitiesDict::iterator p = _nameIdentitiesDict.find("N"); Identities identities; - identities = _nameIdentitiesDict["N"]; + if (p != _nameIdentitiesDict.end()) + { + identities = p->second; + } + identities.push_back(ident); - _nameIdentitiesDict["N"] = identities; + _nameIdentitiesDict.insert(make_pair("N", identities)); // // Turn the identity into a Proxy and return the Proxy to the @@ -155,7 +160,12 @@ PhoneBookI::findContacts(const string& name, const Ice::Current&) // them to the caller. See the comment in getNewIdentity why the // prefix "N" is needed. // - Identities identities = _nameIdentitiesDict["N" + name]; + NameIdentitiesDict::iterator p = _nameIdentitiesDict.find("N" + name); + Identities identities; + if (p != _nameIdentitiesDict.end()) + { + identities = p->second; + } Contacts contacts; contacts.reserve(identities.size()); @@ -203,7 +213,7 @@ PhoneBookI::remove(const Identity& ident, const string& name) } Identities identities = p->second; - identities.erase(remove_if(identities.begin(), identities.end(), bind2nd(equal_to<string>(), ident)), + identities.erase(remove_if(identities.begin(), identities.end(), bind2nd(equal_to<Ice::Identity>(), ident)), identities.end()); if (identities.empty()) @@ -216,7 +226,7 @@ PhoneBookI::remove(const Identity& ident, const string& name) // See the comment in getNewIdentity why the prefix "N" is // needed. // - _nameIdentitiesDict["N" + name] = identities; + _nameIdentitiesDict.insert(make_pair("N" + name, identities)); } } @@ -230,9 +240,14 @@ PhoneBookI::move(const Identity& ident, const string& oldName, const string& new // comment in getNewIdentity why the prefix "N" is needed. // remove(ident, oldName); - Identities identities = _nameIdentitiesDict["N" + newName]; + NameIdentitiesDict::iterator p = _nameIdentitiesDict.find("N" + newName); + Identities identities; + if (p != _nameIdentitiesDict.end()) + { + identities = p->second; + } identities.push_back(ident); - _nameIdentitiesDict["N" + newName] = identities; + _nameIdentitiesDict.insert(make_pair("N" + newName, identities)); } Identity @@ -255,7 +270,7 @@ PhoneBookI::getNewIdentity() } else { - ids = p->second.name; + ids = p->second; assert(ids.size() == 1); #ifdef WIN32 n = _atoi64(ids.front().name.c_str()) + 1; @@ -276,7 +291,7 @@ PhoneBookI::getNewIdentity() id.name = s; ids.clear(); ids.push_back(id); - _nameIdentitiesDict["ID"].name = ids; + _nameIdentitiesDict.insert(make_pair("ID", ids)); id.name = s; id.category = "contact"; diff --git a/cpp/demo/Freeze/phonebook/Server.cpp b/cpp/demo/Freeze/phonebook/Server.cpp index ee5cb1a56b0..b590805e2d3 100644 --- a/cpp/demo/Freeze/phonebook/Server.cpp +++ b/cpp/demo/Freeze/phonebook/Server.cpp @@ -72,7 +72,7 @@ PhoneBookServer::runFreeze(int argc, char* argv[], const DBEnvironmentPtr& dbEnv // Create the phonebook, and add it to the Object Adapter. // PhoneBookIPtr phoneBook = new PhoneBookI(adapter, dbPhoneBook, evictor); - adapter->add(phoneBook, "phonebook"); + adapter->add(phoneBook, Ice::stringToIdentity("phonebook")); // // Create and install a factory and initializer for contacts. diff --git a/cpp/include/Freeze/Map.h b/cpp/include/Freeze/Map.h index d3bad8807cf..11592c8e27c 100644 --- a/cpp/include/Freeze/Map.h +++ b/cpp/include/Freeze/Map.h @@ -20,71 +20,6 @@ namespace Freeze { // -// This wrapper class holds a key/value pair and the associated -// database. Upon assignment it writes the new value into the backing -// database. -// -template <typename key_type, typename value_type, typename KeyCodec, typename ValueCodec> -class DBWrapper -{ -public: - - DBWrapper() - { - } - - DBWrapper(const DBPtr& db, const key_type& key, const value_type& value) : - _db(db), _key(key), _value(value) - { - } - - operator value_type() const - { - return _value; - } - - // - // For MSVC (EvictorI.cpp). TODO: Re-examine. - // - value_type get_value() const - { - return _value; - } - - bool operator!=(const value_type& value) const - { - return _value != value; - } - - bool operator==(const value_type& value) const - { - return _value == value; - } - - DBWrapper& operator=(const value_type& value) - { - Freeze::Key k; - Freeze::Value v; - - IceInternal::InstancePtr instance = IceInternal::getInstance(_db->getCommunicator()); - k = KeyCodec::write(_key, instance); - v = ValueCodec::write(value, instance); - - _db->put(k, v); - - _value = value; - - return *this; - } - -private: - - DBPtr _db; - key_type _key; - value_type _value; -}; - -// // Forward declaration // template <typename key_type, typename mapped_type, typename KeyCodec, typename ValueCodec> @@ -93,86 +28,6 @@ template <typename key_type, typename mapped_type, typename KeyCodec, typename V class ConstDBIterator; // -// It's necessary to have DBPair so that automatic conversion to -// std::pair<key_type, mapped_type> from std::pair<key_type, -// DBWrapper<...> > can work correctly (and global operator== & -// operator!=). -// -template <typename key_type, typename mapped_type, typename KeyCodec, typename ValueCodec> -struct DBPair -{ - typedef key_type first_type; - typedef DBWrapper<key_type, mapped_type, KeyCodec, ValueCodec> second_type; - - first_type first; - second_type second; - - DBPair() : - first(first_type()), second(second_type()) - { - } - - DBPair(const first_type& f, const second_type& s) : - first(f), second(s) - { - } - - ~DBPair() - { - } - - operator std::pair<key_type, mapped_type>() - { - return std::pair<key_type, mapped_type>(first, second); - } -}; - -// -// Global operator== & operator!= for both DBPair & std::pair. -// -template <typename key_type, typename mapped_type, typename KeyCodec, typename ValueCodec> -inline bool operator==(const DBPair<key_type, mapped_type, KeyCodec, ValueCodec>& p1, - const DBPair<key_type, mapped_type, KeyCodec, ValueCodec>& p2) -{ - return p1.first == p2.first && p1.second == p2.second; -} - -template <typename key_type, typename mapped_type, typename KeyCodec, typename ValueCodec> -inline bool operator==(const DBPair<key_type, mapped_type, KeyCodec, ValueCodec>& p1, - const std::pair<key_type, mapped_type>& p2) -{ - return p1.first == p2.first && p1.second == p2.second; -} - -template <typename key_type, typename mapped_type, typename KeyCodec, typename ValueCodec> -inline bool operator==(const std::pair<key_type, mapped_type>& p1, - const DBPair<key_type, mapped_type, KeyCodec, ValueCodec>& p2) -{ - return p1.first == p2.first && p1.second == p2.second; -} - -template <typename key_type, typename mapped_type, typename KeyCodec, typename ValueCodec> -inline bool operator!=(const DBPair<key_type, mapped_type, KeyCodec, ValueCodec>& p1, - const DBPair<key_type, mapped_type, KeyCodec, ValueCodec>& p2) -{ - return p1.first != p2.first || p1.second != p2.second; -} - -template <typename key_type, typename mapped_type, typename KeyCodec, typename ValueCodec> -inline bool operator!=(const DBPair<key_type, mapped_type, KeyCodec, ValueCodec>& p1, - const std::pair<key_type, mapped_type>& p2) -{ - return p1.first != p2.first || p1.second != p2.second; -} - -template <typename key_type, typename mapped_type, typename KeyCodec, typename ValueCodec> -inline bool operator!=(const std::pair<key_type, mapped_type>& p1, - const DBPair<key_type, mapped_type, KeyCodec, ValueCodec>& p2) -{ - return p1.first != p2.first || p1.second != p2.second; -} - -// // This is necessary for MSVC support. // struct DBIteratorBase @@ -181,7 +36,9 @@ struct DBIteratorBase }; // -// Database iterator. This implements a forward iterator. +// Database iterator. This implements a forward iterator with the +// restriction that it's only possible to explicitely write back into +// the database. // // Equality and inequality are based on whether the iterator is // "valid". An valid iterator contains a valid database and cursor @@ -197,28 +54,12 @@ public: typedef ptrdiff_t difference_type; - // - // NOTE: - // - // Normally this would be const key_type, mapped_type. However, - // since there the returned data is always data that is in the - // backing database then it's not necessary - in fact, it screws - // up the operator*() and operator-> methods. - // - typedef std::pair<key_type, mapped_type> value_type; + typedef std::pair<const key_type, const mapped_type> value_type; typedef value_type* pointer; typedef value_type& reference; - // - // This is a special value-type that allows write-back to the - // database. It's necessary to use DBPair so that automatic - // conversion to std::pair<key_type,mapped_type> can work correct - // (and global operator== & !=). - // - typedef DBPair<key_type, mapped_type, KeyCodec, ValueCodec> reference_value_type; - DBIterator(const DBPtr& db, const DBCursorPtr& cursor) : _db(db), _cursor(cursor) { @@ -295,20 +136,35 @@ public: // // value_type& operator*(), value_type operator*() const // - reference_value_type& operator*() const + value_type& operator*() const { key_type key; mapped_type value; getCurrentValue(key, value); - _ref = reference_value_type(key, DBWrapper<key_type, mapped_type, KeyCodec, ValueCodec> (_db, key, value)); + + // + // !IMPORTANT! + // + // This method has to cache the returned value to implement + // operator->(). + // + const_cast<key_type&>(_ref.first) = key; + const_cast<mapped_type&>(_ref.second) = value; return _ref; } + value_type* operator->() { return &(operator*()); } + // - // Special version that allows writing back to the database. + // This special method allows writing back into the database. // - reference_value_type* operator->() { return &(operator*()); } + void set(const mapped_type& value) + { + IceInternal::InstancePtr instance = IceInternal::getInstance(_db->getCommunicator()); + Freeze::Value v = ValueCodec::write(value, instance); + _cursor->set(v); + } private: @@ -349,7 +205,7 @@ private: // Cached last return value. This is so that operator->() can // actually return a pointer. // - mutable reference_value_type _ref; + mutable value_type _ref; }; // @@ -362,15 +218,7 @@ public: typedef ptrdiff_t difference_type; - // - // NOTE: - // - // Normally this would be const key_type, mapped_type. However, - // since there the returned data is always data that is in the - // backing database then it's not necessary - in fact, it screws - // up the operator*() and operator-> methods. - // - typedef std::pair<key_type, mapped_type> value_type; + typedef std::pair<const key_type, const mapped_type> value_type; typedef value_type* pointer; @@ -478,13 +326,24 @@ public: return tmp; } + // + // Note that this doesn't follow the regular iterator mapping: + // + // value_type operator*() const + // value_type& operator*() const { key_type key; mapped_type value; - getCurrentValue(key, value); - _ref = value_type(key, value); + // + // !IMPORTANT! + // + // This method has to cache the returned value to implement + // operator->(). + // + const_cast<key_type&>(_ref.first) = key; + const_cast<mapped_type&>(_ref.second) = value; return _ref; } @@ -533,9 +392,10 @@ private: // // This is an STL container that matches the requirements of a -// Associated Container. It also supports the same interface as a -// Hashed Associative Container, except the hasher & key_equal -// methods. +// Associated Container - with the restriction that operator[] isn't +// implemented. It also supports the same interface as a Hashed +// Associative Container (with the above restrictions), except the +// hasher & key_equal methods. // // TODO: If necessary it would be possible to implement reverse and // bidirectional iterators. @@ -545,15 +405,7 @@ class DBMap { public: - // - // NOTE: - // - // Normally this would be const key_type, mapped_type. However, - // since there the returned data is always data that is in the - // backing database then it's not necessary - in fact, it screws - // up the operator*() and operator-> methods. - // - typedef std::pair<key_type, mapped_type> value_type; + typedef std::pair<const key_type, const mapped_type> value_type; // // These are not supported: @@ -564,24 +416,19 @@ public: typedef DBIterator<key_type, mapped_type, KeyCodec, ValueCodec > iterator; typedef ConstDBIterator<key_type, mapped_type, KeyCodec, ValueCodec > const_iterator; - typedef std::pair<const key_type&, mapped_type>& reference; - typedef const std::pair<const key_type&, mapped_type>& const_reference; - - typedef std::pair<const key_type&, mapped_type>* pointer; - typedef const std::pair<const key_type&, mapped_type>* const_pointer; + // + // No definition for reference, const_reference, pointer or + // const_pointer. + // typedef size_t size_type; typedef ptrdiff_t difference_type; // - // Special type similar to DBIterator::value_type_reference - // - typedef DBWrapper<key_type, mapped_type, KeyCodec, ValueCodec> mapped_type_reference; - - // // Allocators are not supported. // // allocator_type + // // // Constructors @@ -720,33 +567,19 @@ public: return 0xffffffff; // TODO: is this the max? } - mapped_type_reference operator[](const key_type& key) - { - IceInternal::InstancePtr instance = IceInternal::getInstance(_db->getCommunicator()); - Freeze::Key k = KeyCodec::write(key, instance); - mapped_type value; - - try - { - Freeze::Value v = _db->get(k); - ValueCodec::read(value, v, instance); - } - catch(const DBNotFoundException&) - { - value = mapped_type(); - Freeze::Value v = ValueCodec::write(value, instance); - _db->put(k, v); - } - return mapped_type_reference(_db, key, value); - - } + // + // This method isn't implemented. + // + // mapped_type& operator[](const key_type& key) + // // // This method isn't in the STLport library - but it's referenced // in "STL Tutorial and Refrence Guide, Second Edition". It's not // currently implemented. // - //const mapped_type& operator[](const key_type& key) const; + // const mapped_type& operator[](const key_type& key) const; + // // // No allocators. @@ -946,18 +779,19 @@ private: namespace std { +//XXX update template <class key_type, class mapped_type, class KeyCodec, class ValueCodec> -inline pair<key_type, mapped_type>* +inline pair<const key_type, const mapped_type>* value_type(const Freeze::DBIterator<key_type, mapped_type, KeyCodec, ValueCodec>&) { - return (pair<key_type, mapped_type>*)0; + return (pair<const key_type, const mapped_type>*)0; } template <class key_type, class mapped_type, class KeyCodec, class ValueCodec> -inline pair<key_type, mapped_type>* +inline pair<const key_type, const mapped_type>* value_type(const Freeze::ConstDBIterator<key_type, mapped_type, KeyCodec, ValueCodec>&) { - return (pair<key_type, mapped_type>*)0; + return (pair<const key_type, const mapped_type>*)0; } inline forward_iterator_tag iterator_category(const Freeze::DBIteratorBase&) diff --git a/cpp/slice/Freeze/DB.ice b/cpp/slice/Freeze/DB.ice index 6e02e6724b4..16b82baf250 100644 --- a/cpp/slice/Freeze/DB.ice +++ b/cpp/slice/Freeze/DB.ice @@ -213,6 +213,20 @@ local interface DBCursor /** * + * Overwrite the data to which the cursor currently refers. + * + * @param value The value to write into the database + * + * @throws DBDeadlockException Raised if a deadlock occurred. + * + * @throws DBException Raised if any other database failure + * occurred. + * + **/ + void set(Value v) throws DBException; + + /** + * * Move the cursor to the next element in the database. * * @return false if there is no next element in the database, true diff --git a/cpp/src/Freeze/DBI.cpp b/cpp/src/Freeze/DBI.cpp index 86bf0f275f9..e68457aaf70 100644 --- a/cpp/src/Freeze/DBI.cpp +++ b/cpp/src/Freeze/DBI.cpp @@ -370,6 +370,39 @@ DBCursorI::curr(Key& key, Value& value) value = Value(static_cast<Byte*>(dbData.data), static_cast<Byte*>(dbData.data) + dbData.size); } +void +DBCursorI::set(const Value& value) +{ + JTCSyncT<JTCMutex> sync(*this); + + if (!_cursor) + { + ostringstream s; + s << _errorPrefix << "\"" << _name << "\" has been closed"; + DBException ex; + ex.message = s.str(); + throw ex; + } + + DBT dbKey, dbData; + memset(&dbKey, 0, sizeof(dbKey)); + memset(&dbData, 0, sizeof(dbData)); + dbData.data = const_cast<void*>(static_cast<const void*>(value.begin())); + dbData.size = value.size(); + + if (_trace >= 1) + { + ostringstream s; + s << "reading current value from database \"" << _name << "\""; + _communicator->getLogger()->trace("DBCursor", s.str()); + } + + // + // Note that the dbKey element is ignored. + // + checkBerkeleyDBReturn(_cursor->c_put(_cursor, &dbKey, &dbData, DB_CURRENT), _errorPrefix, "DBcursor->c_set"); +} + bool DBCursorI::next() { diff --git a/cpp/src/Freeze/DBI.h b/cpp/src/Freeze/DBI.h index 173c874f6d1..e134e272fd9 100644 --- a/cpp/src/Freeze/DBI.h +++ b/cpp/src/Freeze/DBI.h @@ -93,6 +93,7 @@ public: virtual ::Ice::CommunicatorPtr getCommunicator(); virtual void curr(Key& key, Value& value); + virtual void set(const Value& value); virtual bool next(); virtual bool prev(); virtual void del(); diff --git a/cpp/src/Freeze/EvictorI.cpp b/cpp/src/Freeze/EvictorI.cpp index 8d32ac46059..0dc0267bba7 100644 --- a/cpp/src/Freeze/EvictorI.cpp +++ b/cpp/src/Freeze/EvictorI.cpp @@ -109,7 +109,7 @@ Freeze::EvictorI::createObject(const Identity& ident, const ObjectPtr& servant) // // Save the new Ice Object to the database. // - _dict[ident] = servant; + _dict.insert(make_pair(ident, servant)); add(ident, servant); if (_trace >= 1) @@ -224,7 +224,7 @@ Freeze::EvictorI::locate(const ObjectAdapterPtr& adapter, const Current& current // This should work - but with MSVC for some reason it does not. Re-examine. // //ObjectPtr servant = p->second; - ObjectPtr servant = p->second.get_value(); + ObjectPtr servant = p->second; // // Add the new Servant to the evictor queue. @@ -288,7 +288,7 @@ Freeze::EvictorI::finished(const ObjectAdapterPtr&, const Current& current, { if (!current.nonmutating) { - _dict[current.identity] = servant; + _dict.insert(make_pair(current.identity, servant)); } } @@ -364,7 +364,7 @@ Freeze::EvictorI::evict() // if (_persistenceMode == SaveUponEviction) { - _dict[ident] = element->servant; + _dict.insert(make_pair(ident, element->servant)); } // diff --git a/cpp/test/Freeze/dbmap/Client.cpp b/cpp/test/Freeze/dbmap/Client.cpp index 60685c84cda..b4e444b5ee9 100644 --- a/cpp/test/Freeze/dbmap/Client.cpp +++ b/cpp/test/Freeze/dbmap/Client.cpp @@ -206,14 +206,27 @@ run(int argc, char* argv[], const DBPtr& db) cout << "ok" << endl; cout << "testing operator[]... "; - test(m['d'] == 3); + p = m.find('d'); + test(p != m.end() && p->second == 3); test(m.find('a') == m.end()); - test(m['a'] == 0); - test(m.find('a') != m.end()); - m['a'] = 1; - test(m['a'] == 1); - m['a'] = 0; - test(m['a'] == 0); + m.insert(CharIntMap::value_type('a', 1)); + p = m.find('a'); + test(p != m.end() && p->second == 1); + m.insert(CharIntMap::value_type('a', 0)); + p = m.find('a'); + test(p != m.end() && p->second == 0); + cout << "ok" << endl; + + // + // Test writing into an iterator. + // + cout << "testing iterator.set... "; + p = m.find('a'); + test(p != m.end() && p->second == 0); + p.set(1); + test(p != m.end() && p->second == 1); + p = m.find('a'); + test(p != m.end() && p->second == 1); cout << "ok" << endl; // @@ -251,14 +264,14 @@ run(int argc, char* argv[], const DBPtr& db) // order). // j = find(alphabet.begin(), alphabet.end(), 'n'); - vector<CharIntMap::value_type> pairs; - pairs.push_back(CharIntMap::value_type(*j, j - alphabet.begin())); + vector< pair <char, int> > pairs; + pairs.push_back(make_pair(*j, j - alphabet.begin())); ++j; - pairs.push_back(CharIntMap::value_type(*j, j - alphabet.begin())); + pairs.push_back(make_pair(*j, j - alphabet.begin())); ++j; - pairs.push_back(CharIntMap::value_type(*j, j - alphabet.begin())); + pairs.push_back(make_pair(*j, j - alphabet.begin())); ++j; - pairs.push_back(CharIntMap::value_type(*j, j - alphabet.begin())); + pairs.push_back(make_pair(*j, j - alphabet.begin())); p = find_first_of(m.begin(), m.end(), pairs.begin(), pairs.end()); test(p != m.end()); @@ -274,7 +287,7 @@ run(int argc, char* argv[], const DBPtr& db) copy(m.begin(), m.end(), back_inserter(pairs)); test(pairs.size() == m.size()); - vector<CharIntMap::value_type>::const_iterator pit; + vector<pair<char, int> >::const_iterator pit; for (pit = pairs.begin() ; pit != pairs.end() ; ++pit) { p = m.find(pit->first); |