187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines//===- KeyEntryMap.h ---------------------------------------------------===//
287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines//
387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines//                     The MCLinker Project
487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines//
587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines// This file is distributed under the University of Illinois Open Source
687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines// License. See LICENSE.TXT for details.
787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines//
887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines//===----------------------------------------------------------------------===//
937b74a387bb3993387029859c2d9d051c41c724eStephen Hines#ifndef MCLD_TARGET_KEYENTRYMAP_H_
1037b74a387bb3993387029859c2d9d051c41c724eStephen Hines#define MCLD_TARGET_KEYENTRYMAP_H_
1187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
1287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines#include <list>
1337b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include <vector>
1487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
1587f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesnamespace mcld {
1687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
1787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines/** \class KeyEntryMap
1887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines *  \brief KeyEntryMap is a <const KeyType*, ENTRY*> map.
1987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines */
2037b74a387bb3993387029859c2d9d051c41c724eStephen Hinestemplate <typename KEY, typename ENTRY>
2137b74a387bb3993387029859c2d9d051c41c724eStephen Hinesclass KeyEntryMap {
2237b74a387bb3993387029859c2d9d051c41c724eStephen Hines public:
2337b74a387bb3993387029859c2d9d051c41c724eStephen Hines  typedef KEY KeyType;
2487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  typedef ENTRY EntryType;
2587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
2637b74a387bb3993387029859c2d9d051c41c724eStephen Hines private:
2787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  struct EntryPair {
2887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    EntryPair(EntryType* pEntry1, EntryType* pEntry2)
2937b74a387bb3993387029859c2d9d051c41c724eStephen Hines        : entry1(pEntry1), entry2(pEntry2) {}
3087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
3187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    EntryType* entry1;
3287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    EntryType* entry2;
3387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  };
3487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
3587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  /// EntryOrPair - A key may mapping to a signal entry or a pair of entries,
3687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  /// user is responsible for the type of Mapping.entry
3787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  union EntryOrPair {
3887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    EntryType* entry_ptr;
3987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    EntryPair* pair_ptr;
4087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  };
4187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
4287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  struct Mapping {
4387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    const KeyType* key;
4487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    EntryOrPair entry;
4587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  };
4687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
4787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  typedef std::vector<Mapping> KeyEntryPool;
4887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  typedef std::list<EntryPair> PairListType;
4987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
5037b74a387bb3993387029859c2d9d051c41c724eStephen Hines public:
5187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  typedef typename KeyEntryPool::iterator iterator;
5287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  typedef typename KeyEntryPool::const_iterator const_iterator;
5387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
5437b74a387bb3993387029859c2d9d051c41c724eStephen Hines public:
5587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  /// lookUp - look up the entry mapping to pKey
5687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  const EntryType* lookUp(const KeyType& pKey) const;
5737b74a387bb3993387029859c2d9d051c41c724eStephen Hines  EntryType* lookUp(const KeyType& pKey);
5887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
5987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  /// lookUpFirstEntry - look up the first entry mapping to pKey
6087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  const EntryType* lookUpFirstEntry(const KeyType& pKey) const;
6137b74a387bb3993387029859c2d9d051c41c724eStephen Hines  EntryType* lookUpFirstEntry(const KeyType& pKey);
6287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
6387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  /// lookUpSecondEntry - look up the second entry mapping to pKey
6487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  const EntryType* lookUpSecondEntry(const KeyType& pKey) const;
6537b74a387bb3993387029859c2d9d051c41c724eStephen Hines  EntryType* lookUpSecondEntry(const KeyType& pKey);
6687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
6787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  void record(const KeyType& pKey, EntryType& pEntry);
6837b74a387bb3993387029859c2d9d051c41c724eStephen Hines  void record(const KeyType& pKey, EntryType& pEntry1, EntryType& pEntry2);
6987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
7037b74a387bb3993387029859c2d9d051c41c724eStephen Hines  bool empty() const { return m_Pool.empty(); }
7137b74a387bb3993387029859c2d9d051c41c724eStephen Hines  size_t size() const { return m_Pool.size(); }
7287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
7387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  const_iterator begin() const { return m_Pool.begin(); }
7437b74a387bb3993387029859c2d9d051c41c724eStephen Hines  iterator begin() { return m_Pool.begin(); }
7537b74a387bb3993387029859c2d9d051c41c724eStephen Hines  const_iterator end() const { return m_Pool.end(); }
7637b74a387bb3993387029859c2d9d051c41c724eStephen Hines  iterator end() { return m_Pool.end(); }
7787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
7887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  void reserve(size_t pSize) { m_Pool.reserve(pSize); }
7987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
8037b74a387bb3993387029859c2d9d051c41c724eStephen Hines private:
8187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  KeyEntryPool m_Pool;
8287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
8387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  /// m_Pairs - the EntryPairs
8487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  PairListType m_Pairs;
8587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines};
8687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
8737b74a387bb3993387029859c2d9d051c41c724eStephen Hinestemplate <typename KeyType, typename EntryType>
8837b74a387bb3993387029859c2d9d051c41c724eStephen Hinesconst EntryType* KeyEntryMap<KeyType, EntryType>::lookUp(
8937b74a387bb3993387029859c2d9d051c41c724eStephen Hines    const KeyType& pKey) const {
9087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  const_iterator mapping, mEnd = m_Pool.end();
9187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  for (mapping = m_Pool.begin(); mapping != mEnd; ++mapping) {
9287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    if (mapping->key == &pKey) {
9387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      return mapping->entry.entry_ptr;
9487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    }
9587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  }
9687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
9787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  return NULL;
9887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines}
9987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
10037b74a387bb3993387029859c2d9d051c41c724eStephen Hinestemplate <typename KeyType, typename EntryType>
10137b74a387bb3993387029859c2d9d051c41c724eStephen HinesEntryType* KeyEntryMap<KeyType, EntryType>::lookUp(const KeyType& pKey) {
10287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  iterator mapping, mEnd = m_Pool.end();
10387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  for (mapping = m_Pool.begin(); mapping != mEnd; ++mapping) {
10487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    if (mapping->key == &pKey) {
10587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      return mapping->entry.entry_ptr;
10687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    }
10787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  }
10887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
10987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  return NULL;
11087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines}
11187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
11237b74a387bb3993387029859c2d9d051c41c724eStephen Hinestemplate <typename KeyType, typename EntryType>
11337b74a387bb3993387029859c2d9d051c41c724eStephen Hinesconst EntryType* KeyEntryMap<KeyType, EntryType>::lookUpFirstEntry(
11437b74a387bb3993387029859c2d9d051c41c724eStephen Hines    const KeyType& pKey) const {
11587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  const_iterator mapping, mEnd = m_Pool.end();
11687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  for (mapping = m_Pool.begin(); mapping != mEnd; ++mapping) {
11787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    if (mapping->key == &pKey) {
11887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      return mapping->entry.pair_ptr->entry1;
11987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    }
12087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  }
12187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
12287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  return NULL;
12387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines}
12487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
12537b74a387bb3993387029859c2d9d051c41c724eStephen Hinestemplate <typename KeyType, typename EntryType>
12637b74a387bb3993387029859c2d9d051c41c724eStephen HinesEntryType* KeyEntryMap<KeyType, EntryType>::lookUpFirstEntry(
12737b74a387bb3993387029859c2d9d051c41c724eStephen Hines    const KeyType& pKey) {
12887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  const_iterator mapping, mEnd = m_Pool.end();
12987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  for (mapping = m_Pool.begin(); mapping != mEnd; ++mapping) {
13087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    if (mapping->key == &pKey) {
13187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      return mapping->entry.pair_ptr->entry1;
13287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    }
13387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  }
13487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
13587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  return NULL;
13687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines}
13787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
13837b74a387bb3993387029859c2d9d051c41c724eStephen Hinestemplate <typename KeyType, typename EntryType>
13937b74a387bb3993387029859c2d9d051c41c724eStephen Hinesconst EntryType* KeyEntryMap<KeyType, EntryType>::lookUpSecondEntry(
14037b74a387bb3993387029859c2d9d051c41c724eStephen Hines    const KeyType& pKey) const {
14187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  const_iterator mapping, mEnd = m_Pool.end();
14287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  for (mapping = m_Pool.begin(); mapping != mEnd; ++mapping) {
14387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    if (mapping->key == &pKey) {
14487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      return mapping->entry.pair_ptr->entry2;
14587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    }
14687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  }
14787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
14887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  return NULL;
14987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines}
15087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
15137b74a387bb3993387029859c2d9d051c41c724eStephen Hinestemplate <typename KeyType, typename EntryType>
15237b74a387bb3993387029859c2d9d051c41c724eStephen HinesEntryType* KeyEntryMap<KeyType, EntryType>::lookUpSecondEntry(
15337b74a387bb3993387029859c2d9d051c41c724eStephen Hines    const KeyType& pKey) {
15487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  const_iterator mapping, mEnd = m_Pool.end();
15587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  for (mapping = m_Pool.begin(); mapping != mEnd; ++mapping) {
15687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    if (mapping->key == &pKey) {
15787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      return mapping->entry.pair_ptr->entry2;
15887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    }
15987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  }
16087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
16187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  return NULL;
16287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines}
16387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
16437b74a387bb3993387029859c2d9d051c41c724eStephen Hinestemplate <typename KeyType, typename EntryType>
16537b74a387bb3993387029859c2d9d051c41c724eStephen Hinesvoid KeyEntryMap<KeyType, EntryType>::record(const KeyType& pKey,
16637b74a387bb3993387029859c2d9d051c41c724eStephen Hines                                             EntryType& pEntry) {
16787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  Mapping mapping;
16887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  mapping.key = &pKey;
16987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  mapping.entry.entry_ptr = &pEntry;
17087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  m_Pool.push_back(mapping);
17187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines}
17287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
17337b74a387bb3993387029859c2d9d051c41c724eStephen Hinestemplate <typename KeyType, typename EntryType>
17437b74a387bb3993387029859c2d9d051c41c724eStephen Hinesvoid KeyEntryMap<KeyType, EntryType>::record(const KeyType& pKey,
17537b74a387bb3993387029859c2d9d051c41c724eStephen Hines                                             EntryType& pEntry1,
17637b74a387bb3993387029859c2d9d051c41c724eStephen Hines                                             EntryType& pEntry2) {
17787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  Mapping mapping;
17887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  mapping.key = &pKey;
17987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  m_Pairs.push_back(EntryPair(&pEntry1, &pEntry2));
18087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  mapping.entry.pair_ptr = &m_Pairs.back();
18187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  m_Pool.push_back(mapping);
18287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines}
18387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
18437b74a387bb3993387029859c2d9d051c41c724eStephen Hines}  // namespace mcld
18587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
18637b74a387bb3993387029859c2d9d051c41c724eStephen Hines#endif  // MCLD_TARGET_KEYENTRYMAP_H_
187