mirror of
https://github.com/ultimatepp/ultimatepp.git
synced 2026-05-15 14:16:07 -06:00
163 lines
No EOL
2.5 KiB
C++
163 lines
No EOL
2.5 KiB
C++
#include <Core/Core.h>
|
|
|
|
namespace Upp {
|
|
|
|
int IndexCommon::empty[1] = { -1 };
|
|
|
|
IndexCommon::IndexCommon()
|
|
{
|
|
hash = NULL;
|
|
map = empty;
|
|
mask = 0;
|
|
unlinked = -1;
|
|
}
|
|
|
|
void IndexCommon::Pick(IndexCommon& b)
|
|
{
|
|
Free();
|
|
|
|
hash = b.hash;
|
|
map = b.map;
|
|
mask = b.mask;
|
|
unlinked = b.unlinked;
|
|
|
|
b.hash = NULL;
|
|
b.map = empty;
|
|
b.mask = 0;
|
|
b.unlinked = -1;
|
|
}
|
|
|
|
void IndexCommon::Copy(const IndexCommon& b, int count)
|
|
{
|
|
memcpy_t(hash, b.hash, count);
|
|
mask = b.mask;
|
|
unlinked = b.unlinked;
|
|
|
|
FreeMap();
|
|
map = (int *)MemoryAlloc((mask + 1) * sizeof(int));
|
|
memcpy_t(map, b.map, mask + 1);
|
|
}
|
|
|
|
void IndexCommon::Swap(IndexCommon& b)
|
|
{
|
|
UPP::Swap(hash, b.hash);
|
|
UPP::Swap(map, b.map);
|
|
UPP::Swap(mask, b.mask);
|
|
UPP::Swap(unlinked, b.unlinked);
|
|
}
|
|
|
|
IndexCommon::~IndexCommon()
|
|
{
|
|
Free();
|
|
}
|
|
|
|
void IndexCommon::FreeMap()
|
|
{
|
|
if(map != empty)
|
|
MemoryFree(map);
|
|
}
|
|
|
|
void IndexCommon::Free()
|
|
{
|
|
if(hash)
|
|
MemoryFree(hash);
|
|
FreeMap();
|
|
}
|
|
|
|
void IndexCommon::Remap(int count)
|
|
{
|
|
Fill(map, map + mask + 1, -1);
|
|
for(int i = 0; i < count; i++) // todo: unlinked
|
|
if(hash[i].hash)
|
|
Link(i, hash[i].hash);
|
|
}
|
|
|
|
void IndexCommon::Reindex(int count)
|
|
{
|
|
FreeMap();
|
|
map = (int *)MemoryAlloc((mask + 1) * sizeof(int));
|
|
Remap(count);
|
|
}
|
|
|
|
void IndexCommon::Clear()
|
|
{
|
|
Free();
|
|
hash = NULL;
|
|
map = empty;
|
|
mask = 0;
|
|
unlinked = -1;
|
|
}
|
|
|
|
void IndexCommon::GrowMap(int count)
|
|
{
|
|
mask = (mask << 1) | 3;
|
|
Reindex(count);
|
|
}
|
|
|
|
Vector<int> IndexCommon::GetUnlinked() const
|
|
{
|
|
Vector<int> r;
|
|
int i = unlinked;
|
|
if(i >= 0) {
|
|
do {
|
|
i = hash[i].prev;
|
|
r.Add(i);
|
|
}
|
|
while(i != unlinked);
|
|
}
|
|
return r;
|
|
}
|
|
|
|
void IndexCommon::AdjustMap(int count, int alloc)
|
|
{
|
|
if(alloc == 0) {
|
|
FreeMap();
|
|
map = empty;
|
|
mask = 0;
|
|
return;
|
|
}
|
|
dword msk = 0;
|
|
while(msk < (dword)alloc)
|
|
msk = (msk << 1) | 3;
|
|
if(msk != mask) {
|
|
mask = msk;
|
|
Reindex(count);
|
|
}
|
|
}
|
|
|
|
void IndexCommon::MakeMap(int count)
|
|
{
|
|
mask = 0;
|
|
AdjustMap(count, count);
|
|
}
|
|
|
|
void IndexCommon::Trim(int n, int count)
|
|
{
|
|
if(n == 0) {
|
|
int n = (int)(mask + 1);
|
|
for(int i = 0; i < n; i++)
|
|
map[i] = -1;
|
|
unlinked = -1;
|
|
return;
|
|
}
|
|
|
|
for(int i = n; i < count; i++) { // remove items in trimmed area from buckets / unlinked
|
|
Hash& hh = hash[i];
|
|
if(hh.hash)
|
|
Del(map[hh.hash & mask], hh, i);
|
|
else
|
|
Del(unlinked, hh, i);
|
|
}
|
|
}
|
|
|
|
void IndexCommon::Sweep(int n)
|
|
{
|
|
int ti = 0;
|
|
for(int i = 0; i < n; i++)
|
|
if(hash[i].hash)
|
|
hash[ti++].hash = hash[i].hash;
|
|
Remap(ti);
|
|
unlinked = -1;
|
|
}
|
|
|
|
} |