📄 pinweakhashtable.cs
字号:
namespace Perst.Impl
{
using System;
using Perst;
public class PinWeakHashTable : OidHashTable
{
internal Entry[] table;
internal const float loadFactor = 0.75f;
internal int count;
internal int threshold;
internal bool flushing;
public PinWeakHashTable(int initialCapacity)
{
threshold = (int) (initialCapacity * loadFactor);
table = new Entry[initialCapacity];
}
public bool remove(int oid)
{
lock(this)
{
Entry[] tab = table;
int index = (oid & 0x7FFFFFFF) % tab.Length;
for (Entry e = tab[index], prev = null; e != null; prev = e, e = e.next)
{
if (e.oid == oid)
{
if (prev != null)
{
prev.next = e.next;
}
else
{
tab[index] = e.next;
}
e.clear();
count -= 1;
return true;
}
}
return false;
}
}
public void put(int oid, IPersistent obj)
{
lock(this)
{
Entry[] tab = table;
int index = (oid & 0x7FFFFFFF) % tab.Length;
for (Entry e = tab[index]; e != null; e = e.next)
{
if (e.oid == oid)
{
e.oref.Target = obj;
return ;
}
}
if (count >= threshold && !flushing)
{
// Rehash the table if the threshold is exceeded
rehash();
tab = table;
index = (oid & 0x7FFFFFFF) % tab.Length;
}
// Creates the new entry.
tab[index] = new Entry(oid, new WeakReference(obj), tab[index]);
count++;
}
}
public IPersistent get(int oid)
{
lock(this)
{
Entry[] tab = table;
int index = (oid & 0x7FFFFFFF) % tab.Length;
for (Entry e = tab[index], prev = null; e != null; prev = e, e = e.next)
{
if (e.oid == oid)
{
if (e.pin != null)
{
return e.pin;
}
return (IPersistent)e.oref.Target;
}
}
return null;
}
}
internal void rehash()
{
int oldCapacity = table.Length;
Entry[] oldMap = table;
int i;
for (i = oldCapacity; --i >= 0; )
{
Entry e, next, prev;
for (prev = null, e = oldMap[i]; e != null; e = next)
{
next = e.next;
IPersistent obj = (IPersistent)e.oref.Target;
if ((obj == null || obj.IsDeleted()) && e.pin == null)
{
count -= 1;
e.clear();
if (prev == null)
{
oldMap[i] = next;
}
else
{
prev.next = next;
}
}
else
{
prev = e;
}
}
}
if ((uint)count <= ((uint)threshold >> 1))
{
return ;
}
int newCapacity = oldCapacity * 2 + 1;
Entry[] newMap = new Entry[newCapacity];
threshold = (int) (newCapacity * loadFactor);
table = newMap;
for (i = oldCapacity; --i >= 0; )
{
for (Entry old = oldMap[i]; old != null; )
{
Entry e = old;
old = old.next;
int index = (e.oid & 0x7FFFFFFF) % newCapacity;
e.next = newMap[index];
newMap[index] = e;
}
}
}
public void flush()
{
lock (this)
{
flushing = true;
for (int i = 0; i < table.Length; i++)
{
for (Entry e = table[i]; e != null; e = e.next)
{
IPersistent obj = e.pin;
if (obj != null)
{
e.pin = null;
obj.Store();
}
}
}
flushing = false;
if (count >= threshold)
{
// Rehash the table if the threshold is exceeded
rehash();
}
}
}
public void clear()
{
lock(this)
{
Entry[] tab = table;
for (int i = 0; i < tab.Length; i++)
{
tab[i] = null;
}
count = 0;
}
}
public void invalidate()
{
lock (this)
{
for (int i = 0; i < table.Length; i++)
{
for (Entry e = table[i]; e != null; e = e.next)
{
IPersistent obj = e.pin;
if (obj != null)
{
e.pin = null;
obj.Invalidate();
}
}
table[i] = null;
}
count = 0;
}
}
public void setDirty(IPersistent obj)
{
lock (this)
{
int oid = obj.Oid;
Entry[] tab = table;
int index = (oid & 0x7FFFFFFF) % tab.Length;
for (Entry e = tab[index] ; e != null ; e = e.next)
{
if (e.oid == oid)
{
e.pin = obj;
return;
}
}
}
}
public void clearDirty(IPersistent obj)
{
lock (this)
{
int oid = obj.Oid;
Entry[] tab = table;
int index = (oid & 0x7FFFFFFF) % tab.Length;
for (Entry e = tab[index], prev = null; e != null; prev = e, e = e.next)
{
if (e.oid == oid)
{
e.pin = null;
return;
}
}
}
}
public int size()
{
return count;
}
internal class Entry
{
internal Entry next;
internal WeakReference oref;
internal int oid;
internal IPersistent pin;
internal void clear()
{
oref.Target = null;
oref = null;
pin = null;
next = null;
}
internal Entry(int oid, WeakReference oref, Entry chain)
{
next = chain;
this.oid = oid;
this.oref = oref;
}
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -