diff options
Diffstat (limited to 'gprofng/src/DbeSyncMap.h')
-rw-r--r-- | gprofng/src/DbeSyncMap.h | 224 |
1 files changed, 224 insertions, 0 deletions
diff --git a/gprofng/src/DbeSyncMap.h b/gprofng/src/DbeSyncMap.h new file mode 100644 index 0000000..f13f7b4 --- /dev/null +++ b/gprofng/src/DbeSyncMap.h @@ -0,0 +1,224 @@ +/* Copyright (C) 2021 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 */ |