Skip to content

Instantly share code, notes, and snippets.

@samloeschen
Created March 2, 2020 23:12
Show Gist options
  • Save samloeschen/7179c87289214dc84a2a832ed9055329 to your computer and use it in GitHub Desktop.
Save samloeschen/7179c87289214dc84a2a832ed9055329 to your computer and use it in GitHub Desktop.
ContiguousMap<T>
using System;
public class ContiguousMap<T> {
int[] _idIndexMap;
int[] _idPool;
int _poolCount = 0;
int _nextId = 0;
public T[] values {
get { return _values; }
}
T[] _values;
public int count {
get { return _count; }
}
int _count;
public int capacity {
get { return _capacity; }
}
int _capacity;
public ContiguousMap(int capacity) {
_values = new T[capacity];
_idIndexMap = new int[capacity];
_idPool = new int[capacity];
_capacity = capacity;
for (int i = 0; i < capacity; i++) {
_idIndexMap[i] = -1;
}
}
public T this[int id] {
get {
return _values[_idIndexMap[id]];
}
set {
_values[_idIndexMap[id]] = value;
}
}
public bool TryAdd(T element, out int id, bool allowExpand = true) {
if (_count >= capacity) {
if (allowExpand) {
_capacity *= 2;
_idIndexMap = Expand(_idIndexMap, capacity);
_values = Expand(_values, capacity);
_idPool = Expand(_idPool, capacity);
} else {
id = -1;
return false;
}
}
if (!TryDrainId(out id)) {
id = _nextId;
_nextId++;
}
_idIndexMap[id] = _count;
_values[_count] = element;
_count++;
return true;
}
bool TryDrainId(out int id) {
if (_poolCount == 0) {
id = -1;
return false;
}
id = _idPool[_poolCount - 1];
_poolCount--;
return true;
}
void PoolId(int id) {
_idPool[_poolCount] = id;
_poolCount++;
}
ArrayT[] Expand<ArrayT>(ArrayT[] arr, int newCapacity) {
ArrayT[] newArr = new ArrayT[newCapacity];
Array.Copy(arr, newArr, arr.Length);
return newArr;
}
public bool TryRemove(int id, out T removed) {
int index = _idIndexMap[id];
if (index == -1) {
removed = default(T);
return false;
}
// swap values
removed = _values[index];
_values[index] = _values[count - 1];
_count--;
PoolId(id);
_idIndexMap[id] = 0;
return true;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment