/// <summary> /// 重建数据 /// </summary> protected void create() { int heapIndex = array.Length, newCount = heapIndex << 1, newHeapSize = newCount * sizeof(int); keyValue <keyType, valueType>[] newArray = new keyValue <keyType, valueType> [newCount]; pointer.size newHeap = isStaticUnmanaged ? unmanaged.GetStaticSize(newHeapSize, false) : unmanaged.Get(newHeapSize, false), oldHeap = heap; int * newHeapFixed = newHeap.Int; array.CopyTo(newArray, 0); fastCSharp.unsafer.memory.Copy(heap.Byte, newHeapFixed, newHeapSize >> 1); do { --newCount; newHeapFixed[newCount] = newCount; }while (newCount != heapIndex); array = newArray; heap = newHeap; if (isStaticUnmanaged) { unmanaged.FreeStatic(ref oldHeap); } else { unmanaged.Free(ref oldHeap); } }
/// <summary> /// 唯一静态哈希字典 /// </summary> /// <param name="keys">键值数据集合</param> /// <param name="getValue">数据获取器</param> /// <param name="size">哈希容器尺寸</param> public unsafe uniqueDictionary(keyType[] keys, Func <keyType, valueType> getValue, int size) { int count = keys.length(); if (count > size || size <= 0) { log.Error.Throw(log.exceptionType.IndexOutOfRange); } if (getValue == null) { log.Error.Throw(log.exceptionType.Null); } array = new keyValue <keyType, valueType> [size]; if (count != 0) { int length = ((size + 31) >> 5) << 2; byte * isValue = stackalloc byte[length]; fixedMap map = new fixedMap(isValue, length, 0); foreach (keyType key in keys) { int index = key.GetHashCode(); if ((uint)index >= size) { log.Error.Throw(log.exceptionType.IndexOutOfRange); } if (map.Get(index)) { log.Error.Throw(log.exceptionType.ErrorOperation); } map.Set(index); array[index] = new keyValue <keyType, valueType>(key, getValue(key)); } } }
public bool Top(out keyValue <keyType, valueType> value) { int *heapFixed = heap.Int; if (*heapFixed == 0) { value = default(keyValue <keyType, valueType>); return(false); } value = array[heapFixed[1]]; return(true); }
/// <summary> /// 获取匹配数据 /// </summary> /// <param name="key">哈希键值</param> /// <param name="nullValue">默认空值</param> /// <returns>匹配数据,失败返回默认空值</returns> public valueType Get(keyType key, valueType nullValue) { int index = key.GetHashCode(); if ((uint)index < array.Length) { keyValue <keyType, valueType> value = array[index]; if (key.Equals(value.Key)) { return(value.Value); } } return(nullValue); }
/// <summary> /// 数据排序分组数量 /// </summary> /// <param name="array">数据数组</param> /// <returns>分组数量</returns> public unsafe static keyValue </*Type[0]*/ ulong /*Type[0]*/, int>[] sortGroupCount(this subArray </*Type[0]*/ ulong /*Type[0]*/> array) { if (array.Count != 0) { arrayExtension.sort(array.UnsafeArray, array.StartIndex, array.Count); fixed(/*Type[0]*/ ulong /*Type[0]*/ *valueFixed = array.UnsafeArray) { /*Type[0]*/ ulong /*Type[0]*/ *start = valueFixed + array.StartIndex, lastStart = start, end = start + array.Count; /*Type[0]*/ ulong /*Type[0]*/ value = *start; int count = 1; while (++start != end) { if (*start != value) { ++count; value = *start; } } keyValue </*Type[0]*/ ulong /*Type[0]*/, int>[] values = new keyValue </*Type[0]*/ ulong /*Type[0]*/, int> [count]; value = *(start = lastStart); count = 0; while (++start != end) { if (*start != value) { values[count++].Set(value, (int)(start - lastStart)); value = *start; lastStart = start; } } values[count].Set(value, (int)(start - lastStart)); return(values); } } return(nullValue <keyValue </*Type[0]*/ ulong /*Type[0]*/, int> > .Array); }
/// <summary> /// 唯一静态哈希字典 /// </summary> /// <param name="values">数据集合</param> /// <param name="count">数据数量</param> /// <param name="size">哈希容器尺寸</param> private unsafe void fromArray(keyValue <keyType, valueType>[] values, int count, int size) { int length = ((size + 31) >> 5) << 2; byte * isValue = stackalloc byte[length]; fixedMap map = new fixedMap(isValue, length, 0); do { keyValue <keyType, valueType> value = values[--count]; int index = value.Key.GetHashCode(); if ((uint)index >= size) { log.Error.Throw(log.exceptionType.IndexOutOfRange); } if (map.Get(index)) { log.Error.Throw(log.exceptionType.ErrorOperation); } map.Set(index); array[index] = value; }while (count != 0); }