| /* Copyright (C) 2021-2024 Free Software Foundation, Inc. | |
| Contributed by Oracle. | |
| This file is part of GNU Binutils. | |
| This program is free software; you can redistribute it and/or modify | |
| it under the terms of the GNU General Public License as published by | |
| the Free Software Foundation; either version 3, or (at your option) | |
| any later version. | |
| This program is distributed in the hope that it will be useful, | |
| but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
| GNU General Public License for more details. | |
| You should have received a copy of the GNU General Public License | |
| along with this program; if not, write to the Free Software | |
| Foundation, 51 Franklin Street - Fifth Floor, Boston, | |
| MA 02110-1301, USA. */ | |
| #ifndef _DbeSyncMap_h | |
| #define _DbeSyncMap_h | |
| #include "DbeLock.h" | |
| #include "DbeLinkList.h" | |
| #include "vec.h" | |
| typedef unsigned long hash_ty; | |
| template <class ITEM> class DbeSyncMap : public DbeLock | |
| { | |
| public: | |
| DbeSyncMap (int _chunkSize = DefaultChunkSize); | |
| virtual ~DbeSyncMap (); | |
| void reset (); | |
| ITEM *get (const char *nm, int64_t chksum); | |
| ITEM *sync_create_item (const char *nm, int64_t chksum); | |
| ITEM *get (const char *nm, const char *path, DbeFile *df); | |
| ITEM *sync_create_item (const char *nm, const char *path, DbeFile *df); | |
| virtual void dump (); | |
| Vector<ITEM *> * | |
| values () | |
| { | |
| return items; | |
| }; | |
| private: | |
| hash_ty hash (const char *key); | |
| DbeLinkList<ITEM *> **chunk; | |
| Vector<ITEM *> *items; | |
| long chunkSize; | |
| enum | |
| { | |
| DefaultChunkSize = 1024 | |
| }; | |
| }; | |
| template <class ITEM> | |
| DbeSyncMap<ITEM>::DbeSyncMap (int _chunkSize) | |
| { | |
| chunkSize = _chunkSize; | |
| chunk = new DbeLinkList<ITEM *> * [chunkSize]; | |
| for (long i = 0; i < chunkSize; i++) | |
| chunk[i] = NULL; | |
| items = new Vector<ITEM *>(512); | |
| } | |
| template <class ITEM> | |
| DbeSyncMap<ITEM>::~DbeSyncMap () | |
| { | |
| for (long i = 0; i < chunkSize; i++) | |
| Destroy (chunk[i]); | |
| delete[] chunk; | |
| delete items; | |
| } | |
| template <class ITEM> | |
| void | |
| DbeSyncMap<ITEM>::reset () | |
| { | |
| for (long i = 0; i < chunkSize; i++) | |
| { | |
| Destroy (chunk[i]); | |
| chunk[i] = NULL; | |
| } | |
| items->reset (); | |
| } | |
| template <class ITEM> | |
| ITEM * | |
| DbeSyncMap<ITEM>::get (const char *nm, int64_t chksum) | |
| { | |
| hash_ty h = hash (nm); | |
| for (DbeLinkList<ITEM *> *dl = chunk[h]; dl; dl = dl->get_next ()) | |
| { | |
| ITEM *item = dl->get_item (); | |
| if (item->compare (nm, chksum)) | |
| return item; | |
| } | |
| return NULL; | |
| } | |
| template <class ITEM> | |
| hash_ty | |
| DbeSyncMap<ITEM>::hash (const char *key) | |
| { | |
| return (hash_ty) (crc64 (key, strlen (key)) % chunkSize); | |
| } | |
| template <class ITEM> | |
| ITEM * | |
| DbeSyncMap<ITEM>::sync_create_item (const char *nm, int64_t chksum) | |
| { | |
| hash_ty h = hash (nm); | |
| for (DbeLinkList<ITEM *> *dl = chunk[h]; dl; dl = dl->get_next ()) | |
| { | |
| ITEM *item = dl->get_item (); | |
| if (item->compare (nm, chksum)) | |
| return item; | |
| } | |
| aquireLock (); | |
| for (DbeLinkList<ITEM *> *dl = chunk[h]; dl; dl = dl->get_next ()) | |
| { | |
| ITEM *item = dl->get_item (); | |
| if (item->compare (nm, chksum)) | |
| { | |
| releaseLock (); | |
| return item; | |
| } | |
| } | |
| ITEM *item = ITEM::create_item (nm, chksum); | |
| DbeLinkList<ITEM *> *dl = new DbeLinkList<ITEM *>(item); | |
| dl->set_next (chunk[h]); | |
| chunk[h] = dl; | |
| items->append (item); | |
| releaseLock (); | |
| return item; | |
| } | |
| template <class ITEM> | |
| ITEM * | |
| DbeSyncMap<ITEM>::get (const char *nm, const char *path, DbeFile *df) | |
| { | |
| int mask = 1 + (path != NULL ? 2 : 0) + (df != NULL ? 4 : 0); | |
| hash_ty h = hash (nm); | |
| for (DbeLinkList<ITEM *> *dl = chunk[h]; dl; dl = dl->get_next ()) | |
| { | |
| ITEM *item = dl->get_item (); | |
| if (mask == item->compare (nm, path, df)) | |
| return item; | |
| } | |
| return NULL; | |
| } | |
| template <class ITEM> | |
| ITEM * | |
| DbeSyncMap<ITEM>::sync_create_item (const char *nm, const char *path, DbeFile *df) | |
| { | |
| int mask = CMP_PATH; | |
| if (path != NULL) | |
| mask += CMP_RUNTIMEPATH; | |
| if (df != NULL) | |
| mask += CMP_CHKSUM; | |
| hash_ty h = hash (nm); | |
| for (DbeLinkList<ITEM *> *dl = chunk[h]; dl; dl = dl->get_next ()) | |
| { | |
| ITEM *item = dl->get_item (); | |
| if (mask == item->compare (nm, path, df)) | |
| return item; | |
| } | |
| aquireLock (); | |
| for (DbeLinkList<ITEM *> *dl = chunk[h]; dl; dl = dl->get_next ()) | |
| { | |
| ITEM *item = dl->get_item (); | |
| if (mask == item->compare (nm, path, df)) | |
| { | |
| releaseLock (); | |
| return item; | |
| } | |
| } | |
| ITEM *item = ITEM::create_item (nm, path, df); | |
| DbeLinkList<ITEM *> *dl = new DbeLinkList<ITEM *>(item); | |
| dl->set_next (chunk[h]); | |
| chunk[h] = dl; | |
| items->append (item); | |
| releaseLock (); | |
| return item; | |
| } | |
| template <class ITEM> | |
| void | |
| DbeSyncMap<ITEM>::dump () | |
| { | |
| Dprintf (1, NTXT ("\nDbeSyncMap::dump: vals=%ld\n"), (long) VecSize (items)); | |
| int tot = 0; | |
| int max_cnt = 0; | |
| for (long i = 0; i < chunkSize; i++) | |
| { | |
| DbeLinkList<ITEM *> *lp = chunk[i]; | |
| if (lp) | |
| { | |
| int cnt = 0; | |
| for (DbeLinkList<ITEM *> *lp1 = lp; lp1; lp1 = lp1->get_next ()) | |
| cnt++; | |
| tot += cnt; | |
| if (max_cnt < cnt) | |
| max_cnt = cnt; | |
| cnt = 1; | |
| for (DbeLinkList<ITEM *> *lp1 = lp; lp1; lp1 = lp1->get_next ()) | |
| { | |
| ITEM *p = lp1->get_item (); | |
| Dprintf (1, NTXT (" %2d %s\n"), cnt, p->get_name ()); | |
| cnt++; | |
| } | |
| } | |
| } | |
| Dprintf (1, NTXT ("\nDbeSyncMap::dump: vals=%ld max_cnt=%d tot=%d\n"), | |
| (long) VecSize (items), max_cnt, tot); | |
| } | |
| #endif /* _DbeSyncMap_h */ |