//===- HandleToArea.h -----------------------------------------------------===// // // The MCLinker Project // // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// #ifndef MCLD_FILE_HANDLE_TO_MEMORY_AREA_H #define MCLD_FILE_HANDLE_TO_MEMORY_AREA_H #ifdef ENABLE_UNITTEST #include <gtest.h> #endif #include <mcld/ADT/Uncopyable.h> #include <mcld/ADT/TypeTraits.h> #include <mcld/ADT/StringHash.h> #include <mcld/Support/Path.h> #include <mcld/Support/FileHandle.h> #include <vector> namespace mcld { class MemoryArea; /** \class HandleToArea * * Special double-key associative container. Keys are Path and file handler, * associative value is MemoryArea. * * For high performance, HandleToArea is not designed to contain unique * <key, value> pair. The key and value may be duplicated. * * Like FileHandle, HandleToArea should neither throw exception nor call * expressive diagnostic. */ class HandleToArea : private Uncopyable { private: struct Bucket { unsigned int hash_value; FileHandle* handle; MemoryArea* area; }; // the best data structure is a binary search tree. // However, by the shrinking time-to-market constraint, I used // vector and sequential search here. typedef std::vector<Bucket> HandleToAreaMap; typedef StringHash<BKDR> HashFunction; public: typedef HandleToAreaMap::iterator iterator; typedef HandleToAreaMap::const_iterator const_iterator; public: struct Result { public: Result(FileHandle* pHandle, MemoryArea* pArea) : handle(pHandle), area(pArea) { } public: FileHandle* handle; MemoryArea* area; }; struct ConstResult { public: ConstResult(const FileHandle* pHandle, const MemoryArea* pArea) : handle(pHandle), area(pArea) { } public: const FileHandle* handle; const MemoryArea* area; }; public: bool push_back(FileHandle* pHandle, MemoryArea* pArea); bool erase(MemoryArea* pArea); bool erase(const sys::fs::Path& pPath); Result findFirst(const sys::fs::Path& pPath); ConstResult findFirst(const sys::fs::Path& pPath) const; iterator begin() { return m_AreaMap.begin(); } iterator end() { return m_AreaMap.end(); } const_iterator begin() const { return m_AreaMap.begin(); } const_iterator end() const { return m_AreaMap.end(); } // ----- capacity ----- // bool empty() const { return m_AreaMap.empty(); } size_t size() const { return m_AreaMap.size(); } HandleToArea() : m_AreaMap() { } ~HandleToArea() { } private: HandleToAreaMap m_AreaMap; }; } // namespace of mcld #endif