(root)/
binutils-2.41/
gprofng/
src/
DbeSyncMap.h
       1  /* Copyright (C) 2021-2023 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 */