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

📄 persistentmapimpl.cs

📁 Perst开源实时数据库
💻 CS
📖 第 1 页 / 共 2 页
字号:

namespace Perst.Impl
{
    using System;
    using Perst;
#if USE_GENERICS
    using System.Collections.Generic;
#endif
    using System.Collections;

#if USE_GENERICS
    public class PersistentMapImpl<K,V>:PersistentResource,IPersistentMap<K,V> where K:IComparable where V:class,IPersistent
#else
    public class PersistentMapImpl:PersistentCollection,IPersistentMap
#endif
    {
#if USE_GENERICS
        Index<K,V> index;
        Link<V>  values;
        [NonSerialized] 
        ICollection<V> valueSet;
        [NonSerialized] 
        ICollection<K> keySet;
#else
        Index    index;
        Link     values;
        [NonSerialized] 
        ICollection valueSet;
        [NonSerialized] 
        ICollection keySet;
#endif
        Array keys;
        ClassDescriptor.FieldType type;

        const int BtreeTreshold = 128;

#if USE_GENERICS
        internal PersistentMapImpl(Storage storage, int initialSize) 
            : base(storage)
        {
            keys = new K[initialSize];
            values = storage.CreateLink<V>(initialSize);
        }
#else
        internal PersistentMapImpl(Storage storage, Type keyType, int initialSize) 
            : base(storage)
        {
            type = ClassDescriptor.getTypeCode(keyType);
            keys = new IComparable[initialSize];
            values = storage.CreateLink(initialSize);
        }
#endif

        PersistentMapImpl() {}

                                                                                                                
#if USE_GENERICS
        public int Count 
#else
        public override int Count 
#endif
        {
            get 
            {
                return index != null ? index.Count : values.Count;
            }
        }

#if USE_GENERICS
        public bool IsSynchronized 
        {
            get 
            {
                return true;
            }
        }

        public object SyncRoot 
        {
            get 
            {
                return this;
            }
        }

        public virtual bool Contains(KeyValuePair<K,V> pair) 
        {
            V v;
            return TryGetValue(pair.Key, out v) && pair.Value == v;
        }


        public virtual void CopyTo(KeyValuePair<K,V>[] dst, int i) 
        {
            foreach (KeyValuePair<K,V> pair in this) 
            { 
                dst[i++] = pair;
            }
        }

        public virtual void Add(KeyValuePair<K,V> pair)
        {
            Add(pair.Key, pair.Value);
        }

        public virtual bool Remove(KeyValuePair<K,V> pair) 
        {        
            V v;
            if (TryGetValue(pair.Key, out v) && pair.Value == v)
            {
                return Remove(pair.Key);
            }
            return false;
        }     
#endif 

#if COMPACT_NET_FRAMEWORK
        class NaturalComparer : IComparer 
        {
            public int Compare(object a, object b)
            {
                return ((IComparable)a).CompareTo(b);
            }
        }
        readonly NaturalComparer comparer = new NaturalComparer();
#endif

        int binarySearch(object key) 
        {
#if COMPACT_NET_FRAMEWORK
            return Array.BinarySearch((Array)keys, 0, values.Count, key, comparer);
#else
            return Array.BinarySearch((Array)keys, 0, values.Count, key);
#endif
        }


#if USE_GENERICS
        public bool ContainsKey(K key) 
#else
        public bool Contains(Object key) 
#endif
        {
            if (index != null) 
            { 
                Key k = KeyBuilder.getKeyFromObject(key);
                return index.GetDictionaryEnumerator(k, k, IterationOrder.AscentOrder).MoveNext();
            } 
            else 
            {
                int i = binarySearch(key);
                return i >= 0;
            }
        }

        
#if USE_GENERICS
        public V this[K key] 
        {
            get 
            {
                V val;
                if (!TryGetValue(key, out val)) 
                {
                    throw new KeyNotFoundException();
                }
                return val;
            }                
            set 
            {
                if (index == null) 
                { 
                    int size = values.Count;
                    int i = binarySearch(key);
                    if (i >= 0) 
                    {
                        values[i] = value;
                    } 
                    else 
                    {
                        if (size == BtreeTreshold) 
                        { 
                            index = Storage.CreateIndex<K,V>(true);
                            K[] keys = (K[])this.keys;
                            for (i = 0; i < size; i++) 
                            { 
                                index[keys[i]] = values[i];
                            }                
                            index[key] = value;
                            this.keys = null;
                            this.values = null;                
                            Modify();
                        } 
                        else 
                        {
                            K[] oldKeys = (K[])keys;
							i = ~i;
                            if (size >= oldKeys.Length) 
                            { 
                                K[] newKeys = new K[size+1 > oldKeys.Length*2 ? size+1 : oldKeys.Length*2];
                                Array.Copy(oldKeys, 0, newKeys, 0, i);                
                                Array.Copy(oldKeys, i, newKeys, i+1, size-i);
                                keys = newKeys;
                                newKeys[i] = key;
                            } 
                            else 
                            {
                                Array.Copy(oldKeys, i, oldKeys, i+1, size-i);
                                oldKeys[i] = key;
                            }
                            values.Insert(i, value);
                        }
                    }
                } 
                else 
                { 
                    index[key] = value;
                }
            }
        }
#else
        public object this[object key] 
        {
            get 
            {
                object val;
                TryGetValue(key, out val);
                return val;
            }
            set 
            {
                if (index == null) 
                { 
                    int size = values.Count;
                    int i = binarySearch(key);
                    if (i >= 0) 
                    {
                        values[i] = (IPersistent)value;
                    } 
                    else 
                    {
                        if (size == BtreeTreshold) 
                        { 
                            index = Storage.CreateIndex(Btree.mapKeyType(type), true);
                            object[] keys = (object[])this.keys;
                            for (i = 0; i < size; i++) 
                            { 
                                index[keys[i]] = values[i];
                            }                
                            index[key] = (IPersistent)value;
                            this.keys = null;
                            this.values = null;                
                            Modify();
                        } 
                        else 
                        {
                            object[] oldKeys = (object[])keys;
							i = ~i;
                            if (size >= oldKeys.Length) 
                            { 
                                object[] newKeys = new IComparable[size+1 > oldKeys.Length*2 ? size+1 : oldKeys.Length*2];
                                Array.Copy(oldKeys, 0, newKeys, 0, i);                
                                Array.Copy(oldKeys, i, newKeys, i+1, size-i);
                                keys = newKeys;
                                newKeys[i] = key;
                            } 
                            else 
                            {
                                Array.Copy(oldKeys, i, oldKeys, i+1, size-i);
                                oldKeys[i] = key;
                            }
                            values.Insert(i, (IPersistent)value);
                        }
                    }
                } 
                else 
                { 
                    index[key] = (IPersistent)value;
                }
            }
        }
#endif

#if USE_GENERICS
        public void Add(K key, V val)
        {
            if (!ContainsKey(key)) 
            {
                this[key] = val;
            }
        }
#else
        public void Add(object key, Object val)
        {
            if (!Contains(key)) 
            {
                this[key] = val;
            }
        }
#endif
    
#if USE_GENERICS
        public bool Remove(K key) 
        {
            if (index == null) 
            { 
                int i = binarySearch(key);
                if (i >= 0) 
                {
                    int size = values.Count;
                    Array.Copy(keys, i+1, keys, i, size-i-1);
                    keys.SetValue(null, size-1);
                    values.RemoveAt(i);
                    return true;
                }
                return false;
            } 
            else 
            {
                try 
                { 
                    index.RemoveKey(key);
                    return true;
                } 
                catch (StorageError x) 
                { 
                    if (x.Code == StorageError.ErrorCode.KEY_NOT_FOUND) 
                    { 
                        return false;
                    }
                    throw x;
                }
            }
        }
#else
        public void Remove(object key) 
        {
            if (index == null) 
            { 
                int i = binarySearch(key);
                if (i >= 0) 
                {
                    int size = values.Count;
                    Array.Copy(keys, i+1, keys, i, size-i-1);
                    keys.SetValue(null, size-1);
                    values.Remove(i);
                }
            } 
            else 
            {
                try 
                { 
                    index.Remove(key);
                } 
                catch (StorageError x) 
                { 
                    if (x.Code == StorageError.ErrorCode.KEY_NOT_FOUND) 
                    { 
                        return;
                    }
                    throw x;
                }
            }
        }
#endif
    

        public void Clear() 
        {
            if (index != null) 
            { 
                index.Clear();
            } 
            else 
            {
                values.Clear();
                keys = null;
            }
        }

        public bool IsFixedSize
        {
            get 
            {
                return false;
            }
        }

        public bool IsReadOnly
        {
            get 
            {
                return false;
            }
        }

#if USE_GENERICS
        public bool TryGetValue(K key, out V val)
#else
        public bool TryGetValue(object key, out object val)
#endif
        {
            if (index != null) 
            { 
                return (val = index[key]) != null;
            } 
            else 
            {
                int i = binarySearch(key);
                if (i >= 0) 
                {
                    val = values[i];
                    return true;
                }
                val = null;
                return false;
            }
        }

#if USE_GENERICS
        class PairEnumerator:IEnumerator<KeyValuePair<K,V>> 
        {
            object IEnumerator.Current 
            {
                get
                {
                    return new KeyValuePair<K,V>((K)e.Key, (V)e.Value);
                }
            }
            
            public KeyValuePair<K,V> Current 
            {
                get
                {
                    return new KeyValuePair<K,V>((K)e.Key, (V)e.Value);
                }
            }
            
            public void Reset()
            {
                e.Reset();
            }

            public bool MoveNext()
            {
                return e.MoveNext();
            }

            public void Dispose() {}

            public PairEnumerator(IDictionaryEnumerator e)
            {
                this.e = e;
            }

            IDictionaryEnumerator e;
        }

        public IEnumerator<KeyValuePair<K,V>> GetEnumerator()
        {
            return new PairEnumerator(GetDictionaryEnumerator());
        } 
        
        IEnumerator IEnumerable.GetEnumerator()

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -