summaryrefslogtreecommitdiff
path: root/gprofng/src/DbeSyncMap.h
diff options
context:
space:
mode:
Diffstat (limited to 'gprofng/src/DbeSyncMap.h')
-rw-r--r--gprofng/src/DbeSyncMap.h224
1 files changed, 224 insertions, 0 deletions
diff --git a/gprofng/src/DbeSyncMap.h b/gprofng/src/DbeSyncMap.h
new file mode 100644
index 00000000000..f13f7b422dc
--- /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 */