private void Initialize(IRenderInfoState loadState, int capacity, long defaultValue) { if (defaultValue != 0) { var currentValue = defaultValue; this.initializeStorageInProgress = true; for (int i = 0; capacity > 0; i++) { if (loadState != null) { var loadValue = loadState.GetValueAt(i); currentValue = loadValue.HasValue ? IndexStorage.DoubleToLong(loadValue.Value, IndexStorage.PrecisionMultiplier) : defaultValue; } this[i] = currentValue; capacity--; } this.initializeStorageInProgress = false; this.RefreshAggregateInfo(); } }
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 ResetToDefaultValues(IRenderInfoState loadState, double defaultValue) { this.Clear(); long itemLength = double.IsNaN(defaultValue) ? this.itemDefaultValue : IndexStorage.DoubleToLong(defaultValue, IndexStorage.PrecisionMultiplier); this.Initialize(loadState, this.Count, itemLength); }
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 int IndexFromOffset(double offset) { if (this.aggregateInfoUpdateInProgress) { Debugger.Break(); } long value = IndexStorage.DoubleToLong(offset, IndexStorage.PrecisionMultiplier); if (value > this.aggregateInfo[1]) { return(this.count - 1); } int index = 1; while (index * 2 < this.size) { if (this.aggregateInfo[index * 2] < value) { value -= this.aggregateInfo[index * 2]; index = (index * 2) + 1; } else { index *= 2; } } index = (index * 2) - this.size; while (index < this.size) { if (this[index] < value) { value -= this[index]; index++; } else { break; } } return(Math.Min(index, this.count - 1)); }
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(); }
public void Update(int index, double value) { this[index] = IndexStorage.DoubleToLong(value, IndexStorage.PrecisionMultiplier); }