/* =========================================================================== 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 . =========================================================================== */ using System; namespace Meteor.Common { namespace EfficientHashTables { public class Efficient64bitHashTable { 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][]; } public uint Hash(ulong key) { return (uint)(key % _capacity); } public void Add(ulong key, T value) { uint hsh = Hash(key); 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) { uint hsh = Hash(key); 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) { uint hsh = Hash(key); 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 { 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][]; } public uint Hash(uint key) { return (uint)(key % _capacity); } public void Add(uint key, T value) { uint hsh = Hash(key); 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) { uint hsh = Hash(key); 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; } } } }