2019-06-18 22:55:32 -04:00
|
|
|
|
/*
|
|
|
|
|
===========================================================================
|
|
|
|
|
Copyright (C) 2015-2019 Project Meteor Dev Team
|
|
|
|
|
|
|
|
|
|
This file is part of Project Meteor Server.
|
|
|
|
|
|
|
|
|
|
Project Meteor Server is free software: you can redistribute it and/or modify
|
|
|
|
|
it under the terms of the GNU Affero General Public License as published by
|
|
|
|
|
the Free Software Foundation, either version 3 of the License, or
|
|
|
|
|
(at your option) any later version.
|
|
|
|
|
|
|
|
|
|
Project Meteor Server 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 Affero General Public License for more details.
|
|
|
|
|
|
|
|
|
|
You should have received a copy of the GNU Affero General Public License
|
|
|
|
|
along with Project Meteor Server. If not, see <https:www.gnu.org/licenses/>.
|
|
|
|
|
===========================================================================
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
using System;
|
2016-01-17 11:48:55 -05:00
|
|
|
|
|
2019-06-19 00:05:18 -04:00
|
|
|
|
namespace Meteor.Common
|
2016-01-17 11:48:55 -05:00
|
|
|
|
{
|
|
|
|
|
namespace EfficientHashTables
|
|
|
|
|
{
|
|
|
|
|
public class Efficient64bitHashTable<T>
|
|
|
|
|
{
|
|
|
|
|
private class element
|
|
|
|
|
{
|
|
|
|
|
public ulong _key;
|
|
|
|
|
public T _value;
|
|
|
|
|
};
|
|
|
|
|
private element[][] _buckets;
|
|
|
|
|
private uint _capacity;
|
|
|
|
|
|
|
|
|
|
public Efficient64bitHashTable()
|
|
|
|
|
{
|
|
|
|
|
_capacity = 214373; // some prime number
|
|
|
|
|
_buckets = new element[_capacity][];
|
|
|
|
|
}
|
|
|
|
|
public Efficient64bitHashTable(uint capacity)
|
|
|
|
|
{
|
|
|
|
|
_capacity = capacity;
|
|
|
|
|
_buckets = new element[_capacity][];
|
|
|
|
|
}
|
|
|
|
|
|
2016-06-14 21:29:10 +01:00
|
|
|
|
public uint Hash(ulong key)
|
2016-01-17 11:48:55 -05:00
|
|
|
|
{
|
|
|
|
|
return (uint)(key % _capacity);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void Add(ulong key, T value)
|
|
|
|
|
{
|
2016-06-14 21:29:10 +01:00
|
|
|
|
uint hsh = Hash(key);
|
2016-01-17 11:48:55 -05:00
|
|
|
|
element[] e;
|
|
|
|
|
if (_buckets[hsh] == null)
|
|
|
|
|
_buckets[hsh] = e = new element[1];
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
foreach (var elem in _buckets[hsh])
|
|
|
|
|
if (elem._key == key)
|
|
|
|
|
{
|
|
|
|
|
elem._value = value;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
e = new element[_buckets[hsh].Length + 1];
|
|
|
|
|
Array.Copy(_buckets[hsh], 0, e, 1, _buckets[hsh].Length);
|
|
|
|
|
_buckets[hsh] = e;
|
|
|
|
|
}
|
|
|
|
|
e[0] = new element { _key = key, _value = value };
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public T Get(ulong key)
|
|
|
|
|
{
|
2016-06-14 21:29:10 +01:00
|
|
|
|
uint hsh = Hash(key);
|
2016-01-17 11:48:55 -05:00
|
|
|
|
element[] e = _buckets[hsh];
|
|
|
|
|
if (e == null) return default(T);
|
|
|
|
|
foreach (var f in e)
|
|
|
|
|
if (f._key == key)
|
|
|
|
|
return f._value;
|
|
|
|
|
return default(T);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public bool Has(ulong key)
|
|
|
|
|
{
|
2016-06-14 21:29:10 +01:00
|
|
|
|
uint hsh = Hash(key);
|
2016-01-17 11:48:55 -05:00
|
|
|
|
element[] e = _buckets[hsh];
|
|
|
|
|
if (e == null) return false;
|
|
|
|
|
foreach (var f in e)
|
|
|
|
|
if (f._key == key)
|
|
|
|
|
return true;
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public int Count()
|
|
|
|
|
{
|
|
|
|
|
int r = 0;
|
|
|
|
|
foreach (var e in _buckets)
|
|
|
|
|
if (e != null)
|
|
|
|
|
r += e.Length;
|
|
|
|
|
return r;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public class Efficient32bitHashTable<T>
|
|
|
|
|
{
|
|
|
|
|
private class element
|
|
|
|
|
{
|
|
|
|
|
public uint _key;
|
|
|
|
|
public T _value;
|
|
|
|
|
};
|
|
|
|
|
private element[][] _buckets;
|
|
|
|
|
private uint _capacity;
|
|
|
|
|
|
|
|
|
|
public Efficient32bitHashTable()
|
|
|
|
|
{
|
|
|
|
|
_capacity = 463; // some prime number
|
|
|
|
|
_buckets = new element[_capacity][];
|
|
|
|
|
}
|
|
|
|
|
public Efficient32bitHashTable(uint capacity)
|
|
|
|
|
{
|
|
|
|
|
_capacity = capacity;
|
|
|
|
|
_buckets = new element[_capacity][];
|
|
|
|
|
}
|
|
|
|
|
|
2016-06-14 21:29:10 +01:00
|
|
|
|
public uint Hash(uint key)
|
2016-01-17 11:48:55 -05:00
|
|
|
|
{
|
|
|
|
|
return (uint)(key % _capacity);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void Add(uint key, T value)
|
|
|
|
|
{
|
2016-06-14 21:29:10 +01:00
|
|
|
|
uint hsh = Hash(key);
|
2016-01-17 11:48:55 -05:00
|
|
|
|
element[] e;
|
|
|
|
|
if (_buckets[hsh] == null)
|
|
|
|
|
_buckets[hsh] = e = new element[1];
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
foreach (var elem in _buckets[hsh])
|
|
|
|
|
if (elem._key == key)
|
|
|
|
|
{
|
|
|
|
|
elem._value = value;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
e = new element[_buckets[hsh].Length + 1];
|
|
|
|
|
Array.Copy(_buckets[hsh], 0, e, 1, _buckets[hsh].Length);
|
|
|
|
|
_buckets[hsh] = e;
|
|
|
|
|
}
|
|
|
|
|
e[0] = new element { _key = key, _value = value };
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public T Get(uint key)
|
|
|
|
|
{
|
2016-06-14 21:29:10 +01:00
|
|
|
|
uint hsh = Hash(key);
|
2016-01-17 11:48:55 -05:00
|
|
|
|
element[] e = _buckets[hsh];
|
|
|
|
|
if (e == null) return default(T);
|
|
|
|
|
foreach (var f in e)
|
|
|
|
|
if (f._key == key)
|
|
|
|
|
return f._value;
|
|
|
|
|
return default(T);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public int Count()
|
|
|
|
|
{
|
|
|
|
|
int r = 0;
|
|
|
|
|
foreach (var e in _buckets)
|
|
|
|
|
if (e != null)
|
|
|
|
|
r += e.Length;
|
|
|
|
|
return r;
|
|
|
|
|
}
|
|
|
|
|
|
2016-01-17 23:36:34 -05:00
|
|
|
|
|
|
|
|
|
|
2016-01-17 11:48:55 -05:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|