From: Argyrios Kyrtzidis Date: Fri, 20 Aug 2010 23:31:11 +0000 (+0000) Subject: Add an iterator to OnDiskChainedHashTable to allow iterating over all the key/data... X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=f08b1bb341fde5c755ec3dbe7e1b3114fb7438db;p=clang Add an iterator to OnDiskChainedHashTable to allow iterating over all the key/data pairs. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@111697 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Basic/OnDiskHashTable.h b/include/clang/Basic/OnDiskHashTable.h index aa3f344a6a..8909e47146 100644 --- a/include/clang/Basic/OnDiskHashTable.h +++ b/include/clang/Basic/OnDiskHashTable.h @@ -334,6 +334,71 @@ public: iterator end() const { return iterator(); } + /// \brief Iterates over all the entries in the table, returning + /// a key/data pair. + class item_iterator { + const unsigned char* Ptr; + unsigned NumItemsInBucketLeft; + unsigned NumEntriesLeft; + Info *InfoObj; + public: + typedef std::pair value_type; + + item_iterator(const unsigned char* const Ptr, unsigned NumEntries, + Info *InfoObj) + : Ptr(Ptr), NumItemsInBucketLeft(0), NumEntriesLeft(NumEntries), + InfoObj(InfoObj) { } + item_iterator() + : Ptr(0), NumItemsInBucketLeft(0), NumEntriesLeft(0), InfoObj(0) { } + + bool operator==(const item_iterator& X) const { + return X.NumEntriesLeft == NumEntriesLeft; + } + bool operator!=(const item_iterator& X) const { + return X.NumEntriesLeft != NumEntriesLeft; + } + + item_iterator& operator++() { // Preincrement + if (!NumItemsInBucketLeft) { + // 'Items' starts with a 16-bit unsigned integer representing the + // number of items in this bucket. + NumItemsInBucketLeft = io::ReadUnalignedLE16(Ptr); + } + Ptr += 4; // Skip the hash. + // Determine the length of the key and the data. + const std::pair& L = Info::ReadKeyDataLength(Ptr); + Ptr += L.first + L.second; + assert(NumItemsInBucketLeft); + --NumItemsInBucketLeft; + assert(NumEntriesLeft); + --NumEntriesLeft; + return *this; + } + item_iterator operator++(int) { // Postincrement + item_iterator tmp = *this; ++*this; return tmp; + } + + value_type operator*() const { + const unsigned char* LocalPtr = Ptr; + if (!NumItemsInBucketLeft) + LocalPtr += 2; // number of items in bucket + LocalPtr += 4; // Skip the hash. + + // Determine the length of the key and the data. + const std::pair& L = Info::ReadKeyDataLength(LocalPtr); + + // Read the key. + const internal_key_type& Key = + InfoObj->ReadKey(LocalPtr, L.first); + return std::make_pair(InfoObj->GetExternalKey(Key), + InfoObj->ReadData(Key, LocalPtr + L.first, L.second)); + } + }; + + item_iterator item_begin() { + return item_iterator(Base + 4, getNumEntries(), &InfoObj); + } + item_iterator item_end() { return item_iterator(); } static OnDiskChainedHashTable* Create(const unsigned char* buckets, const unsigned char* const base,