📄 persistentmapimpl.cs
字号:
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 + -