]>
Commit | Line | Data |
---|---|---|
76bdc726 | 1 | /* Copyright (C) 2021-2023 Free Software Foundation, Inc. |
bb368aad VM |
2 | Contributed by Oracle. |
3 | ||
4 | This file is part of GNU Binutils. | |
5 | ||
6 | This program is free software; you can redistribute it and/or modify | |
7 | it under the terms of the GNU General Public License as published by | |
8 | the Free Software Foundation; either version 3, or (at your option) | |
9 | any later version. | |
10 | ||
11 | This program is distributed in the hope that it will be useful, | |
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
14 | GNU General Public License for more details. | |
15 | ||
16 | You should have received a copy of the GNU General Public License | |
17 | along with this program; if not, write to the Free Software | |
18 | Foundation, 51 Franklin Street - Fifth Floor, Boston, | |
19 | MA 02110-1301, USA. */ | |
20 | ||
21 | #ifndef _DbeSyncMap_h | |
22 | #define _DbeSyncMap_h | |
23 | ||
24 | #include "DbeLock.h" | |
25 | #include "DbeLinkList.h" | |
26 | #include "vec.h" | |
27 | ||
28 | typedef unsigned long hash_ty; | |
29 | ||
30 | template <class ITEM> class DbeSyncMap : public DbeLock | |
31 | { | |
32 | public: | |
33 | DbeSyncMap (int _chunkSize = DefaultChunkSize); | |
34 | virtual ~DbeSyncMap (); | |
35 | void reset (); | |
36 | ITEM *get (const char *nm, int64_t chksum); | |
37 | ITEM *sync_create_item (const char *nm, int64_t chksum); | |
38 | ITEM *get (const char *nm, const char *path, DbeFile *df); | |
39 | ITEM *sync_create_item (const char *nm, const char *path, DbeFile *df); | |
40 | virtual void dump (); | |
41 | ||
42 | Vector<ITEM *> * | |
43 | values () | |
44 | { | |
45 | return items; | |
46 | }; | |
47 | ||
48 | private: | |
49 | hash_ty hash (const char *key); | |
50 | ||
51 | DbeLinkList<ITEM *> **chunk; | |
52 | Vector<ITEM *> *items; | |
53 | long chunkSize; | |
54 | ||
55 | enum | |
56 | { | |
57 | DefaultChunkSize = 1024 | |
58 | }; | |
59 | }; | |
60 | ||
61 | template <class ITEM> | |
62 | DbeSyncMap<ITEM>::DbeSyncMap (int _chunkSize) | |
63 | { | |
64 | chunkSize = _chunkSize; | |
65 | chunk = new DbeLinkList<ITEM *> * [chunkSize]; | |
66 | for (long i = 0; i < chunkSize; i++) | |
67 | chunk[i] = NULL; | |
68 | items = new Vector<ITEM *>(512); | |
69 | } | |
70 | ||
71 | template <class ITEM> | |
72 | DbeSyncMap<ITEM>::~DbeSyncMap () | |
73 | { | |
74 | for (long i = 0; i < chunkSize; i++) | |
75 | Destroy (chunk[i]); | |
76 | delete[] chunk; | |
77 | delete items; | |
78 | } | |
79 | ||
80 | template <class ITEM> | |
81 | void | |
82 | DbeSyncMap<ITEM>::reset () | |
83 | { | |
84 | for (long i = 0; i < chunkSize; i++) | |
85 | { | |
86 | Destroy (chunk[i]); | |
87 | chunk[i] = NULL; | |
88 | } | |
89 | items->reset (); | |
90 | } | |
91 | ||
92 | template <class ITEM> | |
93 | ITEM * | |
94 | DbeSyncMap<ITEM>::get (const char *nm, int64_t chksum) | |
95 | { | |
96 | hash_ty h = hash (nm); | |
97 | for (DbeLinkList<ITEM *> *dl = chunk[h]; dl; dl = dl->get_next ()) | |
98 | { | |
99 | ITEM *item = dl->get_item (); | |
100 | if (item->compare (nm, chksum)) | |
101 | return item; | |
102 | } | |
103 | return NULL; | |
104 | } | |
105 | ||
106 | template <class ITEM> | |
107 | hash_ty | |
108 | DbeSyncMap<ITEM>::hash (const char *key) | |
109 | { | |
110 | return (hash_ty) (crc64 (key, strlen (key)) % chunkSize); | |
111 | } | |
112 | ||
113 | template <class ITEM> | |
114 | ITEM * | |
115 | DbeSyncMap<ITEM>::sync_create_item (const char *nm, int64_t chksum) | |
116 | { | |
117 | hash_ty h = hash (nm); | |
118 | for (DbeLinkList<ITEM *> *dl = chunk[h]; dl; dl = dl->get_next ()) | |
119 | { | |
120 | ITEM *item = dl->get_item (); | |
121 | if (item->compare (nm, chksum)) | |
122 | return item; | |
123 | } | |
124 | aquireLock (); | |
125 | for (DbeLinkList<ITEM *> *dl = chunk[h]; dl; dl = dl->get_next ()) | |
126 | { | |
127 | ITEM *item = dl->get_item (); | |
128 | if (item->compare (nm, chksum)) | |
129 | { | |
130 | releaseLock (); | |
131 | return item; | |
132 | } | |
133 | } | |
134 | ITEM *item = ITEM::create_item (nm, chksum); | |
135 | DbeLinkList<ITEM *> *dl = new DbeLinkList<ITEM *>(item); | |
136 | dl->set_next (chunk[h]); | |
137 | chunk[h] = dl; | |
138 | items->append (item); | |
139 | releaseLock (); | |
140 | return item; | |
141 | } | |
142 | ||
143 | template <class ITEM> | |
144 | ITEM * | |
145 | DbeSyncMap<ITEM>::get (const char *nm, const char *path, DbeFile *df) | |
146 | { | |
147 | int mask = 1 + (path != NULL ? 2 : 0) + (df != NULL ? 4 : 0); | |
148 | hash_ty h = hash (nm); | |
149 | for (DbeLinkList<ITEM *> *dl = chunk[h]; dl; dl = dl->get_next ()) | |
150 | { | |
151 | ITEM *item = dl->get_item (); | |
152 | if (mask == item->compare (nm, path, df)) | |
153 | return item; | |
154 | } | |
155 | return NULL; | |
156 | } | |
157 | ||
158 | template <class ITEM> | |
159 | ITEM * | |
160 | DbeSyncMap<ITEM>::sync_create_item (const char *nm, const char *path, DbeFile *df) | |
161 | { | |
162 | int mask = CMP_PATH; | |
163 | if (path != NULL) | |
164 | mask += CMP_RUNTIMEPATH; | |
165 | if (df != NULL) | |
166 | mask += CMP_CHKSUM; | |
167 | hash_ty h = hash (nm); | |
168 | for (DbeLinkList<ITEM *> *dl = chunk[h]; dl; dl = dl->get_next ()) | |
169 | { | |
170 | ITEM *item = dl->get_item (); | |
171 | if (mask == item->compare (nm, path, df)) | |
172 | return item; | |
173 | } | |
174 | aquireLock (); | |
175 | for (DbeLinkList<ITEM *> *dl = chunk[h]; dl; dl = dl->get_next ()) | |
176 | { | |
177 | ITEM *item = dl->get_item (); | |
178 | if (mask == item->compare (nm, path, df)) | |
179 | { | |
180 | releaseLock (); | |
181 | return item; | |
182 | } | |
183 | } | |
184 | ITEM *item = ITEM::create_item (nm, path, df); | |
185 | DbeLinkList<ITEM *> *dl = new DbeLinkList<ITEM *>(item); | |
186 | dl->set_next (chunk[h]); | |
187 | chunk[h] = dl; | |
188 | items->append (item); | |
189 | releaseLock (); | |
190 | return item; | |
191 | } | |
192 | ||
193 | template <class ITEM> | |
194 | void | |
195 | DbeSyncMap<ITEM>::dump () | |
196 | { | |
197 | Dprintf (1, NTXT ("\nDbeSyncMap::dump: vals=%ld\n"), (long) VecSize (items)); | |
198 | int tot = 0; | |
199 | int max_cnt = 0; | |
200 | for (long i = 0; i < chunkSize; i++) | |
201 | { | |
202 | DbeLinkList<ITEM *> *lp = chunk[i]; | |
203 | if (lp) | |
204 | { | |
205 | int cnt = 0; | |
206 | for (DbeLinkList<ITEM *> *lp1 = lp; lp1; lp1 = lp1->get_next ()) | |
207 | cnt++; | |
208 | tot += cnt; | |
209 | if (max_cnt < cnt) | |
210 | max_cnt = cnt; | |
211 | cnt = 1; | |
212 | for (DbeLinkList<ITEM *> *lp1 = lp; lp1; lp1 = lp1->get_next ()) | |
213 | { | |
214 | ITEM *p = lp1->get_item (); | |
215 | Dprintf (1, NTXT (" %2d %s\n"), cnt, p->get_name ()); | |
216 | cnt++; | |
217 | } | |
218 | } | |
219 | } | |
220 | Dprintf (1, NTXT ("\nDbeSyncMap::dump: vals=%ld max_cnt=%d tot=%d\n"), | |
221 | (long) VecSize (items), max_cnt, tot); | |
222 | } | |
223 | ||
224 | #endif /* _DbeSyncMap_h */ |