mirror of
https://github.com/autc04/Retro68.git
synced 2024-06-15 07:29:41 +00:00
225 lines
5.3 KiB
C++
225 lines
5.3 KiB
C++
/* 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 */
|