⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pinweakhashtable.cs

📁 Perst开源实时数据库
💻 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 + -