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