xref: /netbsd-src/external/gpl3/binutils.old/dist/gprofng/src/DbeSyncMap.h (revision c42dbd0ed2e61fe6eda8590caa852ccf34719964)
1 /* Copyright (C) 2021 Free Software Foundation, Inc.
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 *> *
values()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>
DbeSyncMap(int _chunkSize)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>
~DbeSyncMap()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
reset()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 *
get(const char * nm,int64_t chksum)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
hash(const char * key)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 *
sync_create_item(const char * nm,int64_t chksum)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 *
get(const char * nm,const char * path,DbeFile * df)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 *
sync_create_item(const char * nm,const char * path,DbeFile * df)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
dump()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 */
225