internal IndexStorage(int capacity, double defaultVal) { this.itemDefaultValue = IndexStorage.DoubleToLong(defaultVal, IndexStorage.PrecisionMultiplier); IndexStorage.CheckValue(this.itemDefaultValue); this.count = capacity; this.size = 8; if (defaultVal != IndexStorage.UnknownItemLength) { this.knownSizeItemsCount = Math.Max(capacity, this.size); } while (this.size < capacity) { this.size <<= 1; } this.indicesWithValue = new bool[this.size]; this.storage = new long[this.size]; this.aggregateInfo = new long[this.size]; this.averageItemLength = this.itemDefaultValue; this.Initialize(null, capacity, this.itemDefaultValue); }
public void Add(double value) { long val = IndexStorage.DoubleToLong(value, IndexStorage.PrecisionMultiplier); IndexStorage.CheckValue(val); if (this.Count == this.size) { this.ExtendCapacity(this.size * 2); this.RefreshAggregateInfo(); } this.count++; this[this.Count - 1] = val; }
public void Insert(int index, double value) { long val = IndexStorage.DoubleToLong(value, IndexStorage.PrecisionMultiplier); IndexStorage.CheckValue(val); if (this.Count == this.size) { this.ExtendCapacity(this.size * 2); } Array.Copy(this.storage, index, this.storage, index + 1, this.size - index - 1); Array.Copy(this.indicesWithValue, index, this.indicesWithValue, index + 1, this.size - index - 1); this.RefreshAggregateInfo(); this.count++; this[index] = val; }
// Indexer will return average item length if IndexStorage.UnknownItemLength is found. // this.storage will return the actual stored value. // Use indexer to approximate the entire length. private long this[int index] { get { IndexStorage.CheckIndex(index, this.size); long val = this.storage[index]; return(val != IndexStorage.DoubleToLong(IndexStorage.UnknownItemLength, IndexStorage.PrecisionMultiplier) ? val : this.averageItemLength); } set { IndexStorage.CheckIndex(index, this.size); IndexStorage.CheckValue(value); long item = this.storage[index]; if (item == value) { return; } if (LongToDouble(item, IndexStorage.PrecisionMultiplier) == IndexStorage.UnknownItemLength) { this.knownSizeItemsCount++; } if (this.knownSizeItemsCount == 0) { this.averageItemLength = IndexStorage.DefaultAverageItemLength; } else { this.averageItemLength = (long)(this.averageItemLength * (this.knownSizeItemsCount - 1) + value) / this.knownSizeItemsCount; } this.Set(index, value); if (!this.initializeStorageInProgress) { this.RefreshAggregateInfo(); } } }
public void InsertRange(int index, double?value, int insertItemsCount) { long val = 0; if (value.HasValue) { val = IndexStorage.DoubleToLong(value.Value, IndexStorage.PrecisionMultiplier); IndexStorage.CheckValue(val); } int newSize = this.size; while (this.Count + insertItemsCount >= newSize) { newSize *= 2; } if (newSize != this.size) { this.ExtendCapacity(newSize); } Array.Copy(this.storage, index, this.storage, index + insertItemsCount, this.size - index - insertItemsCount); Array.Copy(this.indicesWithValue, index, this.indicesWithValue, index + insertItemsCount, this.size - index - insertItemsCount); this.count += insertItemsCount; for (int i = 0; i < insertItemsCount; i++) { if (value.HasValue) { this[index + i] = val; this.indicesWithValue[index + i] = true; this.HasUpdatedValues = true; } } this.RefreshAggregateInfo(); }