/* * PROGRAM: Client/Server Common Code * MODULE: StringMap.h * DESCRIPTION: Secure handling of clumplet buffers * * The contents of this file are subject to the Initial * Developer's Public License Version 1.0 (the "License"); * you may not use this file except in compliance with the * License. You may obtain a copy of the License at * http://www.ibphoenix.com/main.nfs?a=ibphoenix&page=ibp_idpl. * * Software distributed under the License is distributed AS IS, * WITHOUT WARRANTY OF ANY KIND, either express or implied. * See the License for the specific language governing rights * and limitations under the License. * * The Original Code was created by Nickolay Samofatov * for the Firebird Open Source RDBMS project. * * Copyright (c) 2004 Nickolay Samofatov * and all contributors signed below. * * All Rights Reserved. * Contributor(s): ______________________________________. * * */ #ifndef STRINGMAP_H #define STRINGMAP_H #include "../common/classes/fb_string.h" #include "../common/classes/fb_pair.h" #include "../common/classes/tree.h" namespace Firebird { // // Generic map which allows to have POD and non-POD keys and values. // The class is memory pools friendly. // // Usage // // POD key (integer), non-POD value (string): // GenericMap > > // // non-POD key (string), POD value (integer): // GenericMap > > // // non-POD key (string), non-POD value (string): // GenericMap > > // template > class GenericMap : public AutoStorage { public: typedef typename KeyValuePair::first_type KeyType; typedef typename KeyValuePair::second_type ValueType; typedef BePlusTree, KeyComparator> ValuesTree; class Accessor { public: explicit Accessor(GenericMap* map) : m_Accessor(&map->tree) {} KeyValuePair* current() const { return m_Accessor.current(); } bool getFirst() { return m_Accessor.getFirst(); } bool getNext() { return m_Accessor.getNext(); } private: Accessor(const Accessor&); Accessor& operator=(const Accessor&); typename ValuesTree::Accessor m_Accessor; }; friend class Accessor; GenericMap() : tree(&getPool()), mCount(0) { } explicit GenericMap(MemoryPool& a_pool) : AutoStorage(a_pool), tree(&getPool()), mCount(0) { } ~GenericMap() { clear(); } void assign(GenericMap& v) { clear(); GenericMap::Accessor accessor(&v); for (bool found = accessor.getFirst(); found; found = accessor.getNext()) { const KeyValuePair* const current_pair = accessor.current(); put(current_pair->first, current_pair->second); } } void takeOwnership(GenericMap& from) { fb_assert(this != &from); clear(); tree = from.tree; mCount = from.mCount; ValuesTree::Accessor treeAccessor(&from.tree); if (treeAccessor.getFirst()) { while (true) { bool haveMore = treeAccessor.fastRemove(); if (!haveMore) break; } } from.mCount = 0; } // Clear the map void clear() { ValuesTree::Accessor treeAccessor(&tree); if (treeAccessor.getFirst()) { while (true) { KeyValuePair* temp = treeAccessor.current(); bool haveMore = treeAccessor.fastRemove(); delete temp; if (!haveMore) break; } } mCount = 0; } // Returns true if value existed bool remove(const KeyType& key) { ValuesTree::Accessor treeAccessor(&tree); if (treeAccessor.locate(key)) { KeyValuePair* var = treeAccessor.current(); treeAccessor.fastRemove(); delete var; mCount--; return true; } return false; } // Returns true if value existed previously bool put(const KeyType& key, const ValueType& value) { ValuesTree::Accessor treeAccessor(&tree); if (treeAccessor.locate(key)) { treeAccessor.current()->second = value; return true; } KeyValuePair* var = FB_NEW(getPool()) KeyValuePair(getPool(), key, value); tree.add(var); mCount++; return false; } // Returns pointer to the added empty value or null when key already exists ValueType* put(const KeyType& key) { ValuesTree::Accessor treeAccessor(&tree); if (treeAccessor.locate(key)) { return NULL; } KeyValuePair* var = FB_NEW(getPool()) KeyValuePair(getPool()); var->first = key; tree.add(var); mCount++; return &var->second; } // Returns true if value is found bool get(const KeyType& key, ValueType& value) { ValuesTree::Accessor treeAccessor(&tree); if (treeAccessor.locate(key)) { value = treeAccessor.current()->second; return true; } return false; } // Returns pointer to the found value or null otherwise ValueType* get(const KeyType& key) { ValuesTree::Accessor treeAccessor(&tree); if (treeAccessor.locate(key)) { return &treeAccessor.current()->second; } return NULL; } bool exist(const KeyType& key) { return ValuesTree::Accessor(&tree).locate(key); } size_t count() const { return mCount; } private: ValuesTree tree; size_t mCount; }; typedef GenericMap > > StringMap; } #endif