OLD | NEW |
| (Empty) |
1 // Copyright 2014 PDFium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com | |
6 | |
7 #include "core/fxcrt/fx_basic.h" | |
8 #include "core/fxcrt/plex.h" | |
9 | |
10 CFX_MapPtrToPtr::CFX_MapPtrToPtr(int nBlockSize) | |
11 : m_pHashTable(nullptr), | |
12 m_nHashTableSize(17), | |
13 m_nCount(0), | |
14 m_pFreeList(nullptr), | |
15 m_pBlocks(nullptr), | |
16 m_nBlockSize(nBlockSize) { | |
17 ASSERT(m_nBlockSize > 0); | |
18 } | |
19 | |
20 void CFX_MapPtrToPtr::RemoveAll() { | |
21 FX_Free(m_pHashTable); | |
22 m_pHashTable = nullptr; | |
23 m_nCount = 0; | |
24 m_pFreeList = nullptr; | |
25 if (m_pBlocks) { | |
26 m_pBlocks->FreeDataChain(); | |
27 m_pBlocks = nullptr; | |
28 } | |
29 } | |
30 | |
31 CFX_MapPtrToPtr::~CFX_MapPtrToPtr() { | |
32 RemoveAll(); | |
33 ASSERT(m_nCount == 0); | |
34 } | |
35 uint32_t CFX_MapPtrToPtr::HashKey(void* key) const { | |
36 return ((uint32_t)(uintptr_t)key) >> 4; | |
37 } | |
38 void CFX_MapPtrToPtr::GetNextAssoc(FX_POSITION& rNextPosition, | |
39 void*& rKey, | |
40 void*& rValue) const { | |
41 ASSERT(m_pHashTable); | |
42 CAssoc* pAssocRet = (CAssoc*)rNextPosition; | |
43 ASSERT(pAssocRet); | |
44 if (pAssocRet == (CAssoc*)-1) { | |
45 for (uint32_t nBucket = 0; nBucket < m_nHashTableSize; nBucket++) { | |
46 pAssocRet = m_pHashTable[nBucket]; | |
47 if (pAssocRet) | |
48 break; | |
49 } | |
50 ASSERT(pAssocRet); | |
51 } | |
52 CAssoc* pAssocNext = pAssocRet->pNext; | |
53 for (uint32_t nBucket = (HashKey(pAssocRet->key) % m_nHashTableSize) + 1; | |
54 nBucket < m_nHashTableSize && !pAssocNext; nBucket++) { | |
55 pAssocNext = m_pHashTable[nBucket]; | |
56 } | |
57 rNextPosition = (FX_POSITION)pAssocNext; | |
58 rKey = pAssocRet->key; | |
59 rValue = pAssocRet->value; | |
60 } | |
61 bool CFX_MapPtrToPtr::Lookup(void* key, void*& rValue) const { | |
62 uint32_t nHash; | |
63 CAssoc* pAssoc = GetAssocAt(key, nHash); | |
64 if (!pAssoc) { | |
65 return false; | |
66 } | |
67 rValue = pAssoc->value; | |
68 return true; | |
69 } | |
70 | |
71 void* CFX_MapPtrToPtr::GetValueAt(void* key) const { | |
72 uint32_t nHash; | |
73 CAssoc* pAssoc = GetAssocAt(key, nHash); | |
74 return pAssoc ? pAssoc->value : nullptr; | |
75 } | |
76 | |
77 void*& CFX_MapPtrToPtr::operator[](void* key) { | |
78 uint32_t nHash; | |
79 CAssoc* pAssoc = GetAssocAt(key, nHash); | |
80 if (!pAssoc) { | |
81 if (!m_pHashTable) | |
82 InitHashTable(m_nHashTableSize); | |
83 pAssoc = NewAssoc(); | |
84 pAssoc->key = key; | |
85 pAssoc->pNext = m_pHashTable[nHash]; | |
86 m_pHashTable[nHash] = pAssoc; | |
87 } | |
88 return pAssoc->value; | |
89 } | |
90 CFX_MapPtrToPtr::CAssoc* CFX_MapPtrToPtr::GetAssocAt(void* key, | |
91 uint32_t& nHash) const { | |
92 nHash = HashKey(key) % m_nHashTableSize; | |
93 if (!m_pHashTable) { | |
94 return nullptr; | |
95 } | |
96 CAssoc* pAssoc; | |
97 for (pAssoc = m_pHashTable[nHash]; pAssoc; pAssoc = pAssoc->pNext) { | |
98 if (pAssoc->key == key) | |
99 return pAssoc; | |
100 } | |
101 return nullptr; | |
102 } | |
103 CFX_MapPtrToPtr::CAssoc* CFX_MapPtrToPtr::NewAssoc() { | |
104 if (!m_pFreeList) { | |
105 CFX_Plex* newBlock = CFX_Plex::Create(m_pBlocks, m_nBlockSize, | |
106 sizeof(CFX_MapPtrToPtr::CAssoc)); | |
107 CFX_MapPtrToPtr::CAssoc* pAssoc = | |
108 (CFX_MapPtrToPtr::CAssoc*)newBlock->data(); | |
109 pAssoc += m_nBlockSize - 1; | |
110 for (int i = m_nBlockSize - 1; i >= 0; i--, pAssoc--) { | |
111 pAssoc->pNext = m_pFreeList; | |
112 m_pFreeList = pAssoc; | |
113 } | |
114 } | |
115 CFX_MapPtrToPtr::CAssoc* pAssoc = m_pFreeList; | |
116 m_pFreeList = m_pFreeList->pNext; | |
117 m_nCount++; | |
118 ASSERT(m_nCount > 0); | |
119 pAssoc->key = 0; | |
120 pAssoc->value = 0; | |
121 return pAssoc; | |
122 } | |
123 void CFX_MapPtrToPtr::InitHashTable(uint32_t nHashSize, bool bAllocNow) { | |
124 ASSERT(m_nCount == 0); | |
125 ASSERT(nHashSize > 0); | |
126 FX_Free(m_pHashTable); | |
127 m_pHashTable = nullptr; | |
128 if (bAllocNow) { | |
129 m_pHashTable = FX_Alloc(CAssoc*, nHashSize); | |
130 } | |
131 m_nHashTableSize = nHashSize; | |
132 } | |
133 bool CFX_MapPtrToPtr::RemoveKey(void* key) { | |
134 if (!m_pHashTable) { | |
135 return false; | |
136 } | |
137 CAssoc** ppAssocPrev; | |
138 ppAssocPrev = &m_pHashTable[HashKey(key) % m_nHashTableSize]; | |
139 CAssoc* pAssoc; | |
140 for (pAssoc = *ppAssocPrev; pAssoc; pAssoc = pAssoc->pNext) { | |
141 if (pAssoc->key == key) { | |
142 *ppAssocPrev = pAssoc->pNext; | |
143 FreeAssoc(pAssoc); | |
144 return true; | |
145 } | |
146 ppAssocPrev = &pAssoc->pNext; | |
147 } | |
148 return false; | |
149 } | |
150 void CFX_MapPtrToPtr::FreeAssoc(CFX_MapPtrToPtr::CAssoc* pAssoc) { | |
151 pAssoc->pNext = m_pFreeList; | |
152 m_pFreeList = pAssoc; | |
153 m_nCount--; | |
154 ASSERT(m_nCount >= 0); | |
155 if (m_nCount == 0) { | |
156 RemoveAll(); | |
157 } | |
158 } | |
OLD | NEW |