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 *> * 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 */ 225