public void EnumerateDifferenceAt(int offsetLength, int timeIndex, NaiadList <Weighted <S> > toFill) { if (toFill.Count == 0) { var temp = new OffsetLength(offsetLength); var accum = new CollectionTraceWithAggregationIncrement <S>(); var handle = increments.Dereference(temp); for (int i = 0; i < handle.Length && !handle.Array[handle.Offset + i].IsEmpty(isZero); i++) { if (handle.Array[handle.Offset + i].TimeIndex == timeIndex) { accum.Add(handle.Array[handle.Offset + i], axpy); } } if (!accum.IsEmpty(isZero)) { toFill.Add(new Weighted <S>(accum.Value, 1)); } } else { throw new NotImplementedException(); } }
public void EnumerateCollectionAt(int offsetLength, int timeIndex, NaiadList <Weighted <S> > toFill) { if (toFill.Count == 0) { var temp = new OffsetLength(offsetLength); var weight = UpdateAccumulation(ref temp, timeIndex); if (weight != 0) { toFill.Add(new Weighted <S>(default(S), weight)); } } else { var temp = new OffsetLength(offsetLength); var weight = UpdateAccumulation(ref temp, timeIndex); toFill.Array[0].weight += weight; if (toFill.Array[0].weight == 0) { toFill.Clear(); } } //throw new NotImplementedException(); }
public void IntroduceFrom(ref int thisKeyIndex, ref int thatKeyIndex, bool delete = true) { if (delete && thisKeyIndex == 0) { thisKeyIndex = thatKeyIndex; thatKeyIndex = 0; ReleaseCache(); } else { var ol1 = new OffsetLength(thisKeyIndex); var ol2 = new OffsetLength(thatKeyIndex); if (!ol2.IsEmpty) { IntroduceIncrements(ref ol1, ol2, 1); thisKeyIndex = ol1.offsetLength; if (delete) { ZeroState(ref thatKeyIndex); } ReleaseCache(); } } }
public void EnumerateTimes(int keyIndex, NaiadList <int> timelist) { var ol = new OffsetLength(keyIndex); if (timelist.Count == 0) { var handle = increments.Dereference(ol); for (int i = 0; i < handle.Length && !handle.Array[handle.Offset + i].IsEmpty; i++) { timelist.Add(handle.Array[handle.Offset + i].TimeIndex); } } else { hashSet.Clear(); for (int i = 0; i < timelist.Count; i++) { hashSet.Add(timelist.Array[i]); } var handle = increments.Dereference(ol); for (int i = 0; i < handle.Length && !handle.Array[handle.Offset + i].IsEmpty; i++) { var time = handle.Array[handle.Offset + i].TimeIndex; if (!hashSet.Contains(time)) { timelist.Add(time); hashSet.Add(time); } } } }
void Introduce(ref OffsetLength offsetLength, S element, Int64 weight, int timeIndex) { if (weight != 0) { var handle = EnsureTime(ref offsetLength, timeIndex); var position = 0; while (handle.Array[handle.Offset + position].TimeIndex != timeIndex) { position++; } handle.Array[handle.Offset + position].Weight += weight; // if the introduction results in an empty region, we need to clean up if (handle.Array[handle.Offset + position].IsEmpty) { // drag everything after it down one for (int i = position + 1; i < handle.Length; i++) { handle.Array[handle.Offset + i - 1] = handle.Array[handle.Offset + i]; } handle.Array[handle.Offset + handle.Length - 1] = new CollectionTraceWithoutHeapIncrement(); // if the root element is empty, the list must be empty if (handle.Array[handle.Offset].IsEmpty) { increments.Release(ref offsetLength); } } } }
Handle <CollectionTraceWithoutHeapIncrement> EnsureTime(ref OffsetLength offsetLength, int timeIndex) { var handle = increments.Dereference(offsetLength); for (int i = 0; i < handle.Length; i++) { // if we found the time, it is ensured and we can return if (handle.Array[handle.Offset + i].TimeIndex == timeIndex) { return(handle); } // if we found an empty slot, new it up and return if (handle.Array[handle.Offset + i].IsEmpty) { handle.Array[handle.Offset + i] = new CollectionTraceWithoutHeapIncrement(timeIndex); return(handle); } } // if we didn't find it, and no empty space for it var oldLength = handle.Length; handle = increments.EnsureAllocation(ref offsetLength, handle.Length + 1); handle.Array[handle.Offset + oldLength] = new CollectionTraceWithoutHeapIncrement(timeIndex); return(handle); }
public void ReleaseCache() { if (!cachedIncrementOffset.IsEmpty) { cachedIncrementOffset = new OffsetLength(); cacheContents = new CollectionTraceWithAggregationIncrement <S>(); } }
public void ReleaseCache() { if (!cachedIncrementOffset.IsEmpty) { cachedWeight = 0; cachedIncrementOffset = new OffsetLength(); cachedTimeIndex = 0; } }
void Introduce(ref OffsetLength thisOffsetLength, OffsetLength thatOffsetLength, int scale) { var handle = increments.Dereference(thatOffsetLength); for (int i = 0; i < handle.Length && !handle.Array[handle.Offset + i].IsEmpty; i++) { Introduce(ref thisOffsetLength, default(S), scale * handle.Array[handle.Offset + i].Weight, handle.Array[handle.Offset + i].TimeIndex); } }
public void ReleaseCache() { // only release if tracking a key if (!cachedIncrementOffset.IsEmpty) { records.Release(ref cachedRecordsOffset); cachedIncrementOffset = new OffsetLength(); cachedTimeIndex = 0; } }
public void Introduce(ref int offsetLength, S element, Int64 weight, int timeIndex) { var ol = new OffsetLength(offsetLength); Introduce(ref ol, element, weight, timeIndex); offsetLength = ol.offsetLength; ReleaseCache(); }
public void SubtractStrictlyPriorDifferences(ref int keyIndex, int timeIndex) { var ol = new OffsetLength(keyIndex); // if there aren't any strictly prior differences we can just return if (ol.IsEmpty) { return; } var handle = EnsureTime(ref ol, timeIndex); var position = 0; while (handle.Array[handle.Offset + position].TimeIndex != timeIndex) { position++; } // if the destination time is empty, we can swap in the accumulation (negated) if (!handle.Array[handle.Offset + position].IsEmpty) { // swap the accumulation in, and zero out the accumulation (the new correct accumulation for this key). handle.Array[handle.Offset + position] = new CollectionTraceWithoutHeapIncrement(-1 * UpdateAccumulation(ref ol, timeIndex), timeIndex); // we may have ended up with a null acculumation, must clean up if (handle.Array[handle.Offset + position].Weight == 0) { for (int i = position + 1; i < handle.Length; i++) { handle.Array[handle.Offset + i - 1] = handle.Array[handle.Offset + i]; } handle.Array[handle.Offset + handle.Length - 1] = new CollectionTraceWithoutHeapIncrement(); if (handle.Array[handle.Offset].Weight == 0) { increments.Release(ref ol); } } // important to update the cached accumulation to reflect the emptiness // only do this if the cached accumulation is what we are working with if (cachedIncrementOffset.offsetLength == ol.offsetLength) { cachedWeight = 0; cachedIncrementOffset = ol; cachedTimeIndex = timeIndex; } } else { throw new Exception("Attemping subtraction from non-empty time; something wrong in Operator logic"); } keyIndex = ol.offsetLength; }
protected Handle <Weighted <S> > EnsureAllocation(ref OffsetLength ol, int newLength) { var handle = records.Dereference(ol); if (newLength > handle.Length) { var newOl = new OffsetLength(); var newHandle = records.Allocate(out newOl, newLength); #if false if (newHandle.Length < HashTableThresholdCount) { for (int i = 0; i < handle.Length; i++) { newHandle.Array[newHandle.Offset + i] = handle.Array[handle.Offset + i]; } for (int i = handle.Length; i < newHandle.Length; i++) { newHandle.Array[newHandle.Offset + i] = new Weighted <S>(); } } else { for (int i = 0; i < handle.Length && handle.Array[handle.Offset + i].weight != 0; i++) { IntroduceAsHashTable(ref newOl, handle.Array[handle.Offset + i].record, handle.Array[handle.Offset + i].weight); } } #else for (int i = 0; i < newHandle.Length; i++) { newHandle.Array[newHandle.Offset + i] = new Weighted <S>(); } for (int i = 0; i < handle.Length; i++) { if (handle.Array[handle.Offset + i].weight != 0) { Introduce(ref newOl, handle.Array[handle.Offset + i].record, handle.Array[handle.Offset + i].weight); } } #endif records.Release(ref ol); ol = newOl; //return newHandle; return(records.Dereference(ol)); } else { return(handle); } }
public void EnumerateDifferenceAt(int offsetLength, int timeIndex, NaiadList <Weighted <S> > toFill) { if (toFill.Count == 0) { var temp = new OffsetLength(offsetLength); var handle = EnumerateDifferenceAt(ref temp, timeIndex); for (int i = 0; i < handle.Length; i++) { if (handle.Array[handle.Offset + i].weight != 0) { toFill.Add(handle.Array[handle.Offset + i]); } } } else { accumulationNotes.Clear(); for (int i = 0; i < toFill.Count; i++) { accumulationNotes[toFill.Array[i].record] = i; } var temp = new OffsetLength(offsetLength); var handle = EnumerateDifferenceAt(ref temp, timeIndex); for (int i = 0; i < handle.Length; i++) { if (handle.Array[handle.Offset + i].weight != 0) { var index = 0; if (accumulationNotes.TryGetValue(handle.Array[handle.Offset + i].record, out index)) { toFill.Array[index].weight += handle.Array[handle.Offset + i].weight; } else { toFill.Add(handle.Array[handle.Offset + i]); } } } var counter = 0; for (int i = 0; i < toFill.Count; i++) { if (toFill.Array[i].weight != 0) { toFill.Array[counter++] = toFill.Array[i]; } } toFill.Count = counter; } }
void Introduce(ref OffsetLength offsetLength, S element, Int64 weight) { if (!offsetLength.IsEmpty && records.heaps[offsetLength.Length].Length >= HashTableThresholdCount) { IntroduceAsHashTable(ref offsetLength, element, weight); } else { IntroduceAsUnsortedList(ref offsetLength, element, weight); } }
public void Introduce(ref int offsetLength, S element, Int64 weight, int timeIndex) { var ol = new OffsetLength(offsetLength); // internal Introduce uses aggregated element and weight, so should aggregate first Introduce(ref ol, this.axpy(weight, element, default(S)), weight, timeIndex); offsetLength = ol.offsetLength; ReleaseCache(); }
public void EnsureStateIsCurrentWRTAdvancedTimes(ref int offsetLength) { var ol = new OffsetLength(offsetLength); if (!ol.IsEmpty) { var handle = increments.Dereference(ol); for (int i = 0; i < handle.Length; i++) { if (!handle.Array[handle.Offset + i].IsEmpty) { var newIndex = UpdateTime(handle.Array[handle.Offset + i].TimeIndex); // if the time has changed, we may need to collapse the increment //if (handle.Array[handle.Offset + i].TimeIndex != newIndex) { handle.Array[handle.Offset + i].TimeIndex = newIndex; // scan the entire array, stopping early if we have emptied the source increment for (int j = 0; j < i && !handle.Array[handle.Offset + i].IsEmpty; j++) { // if we find another location, not at i, add stuff in there. We should only find one (otherwise, error) if (handle.Array[handle.Offset + j].TimeIndex == handle.Array[handle.Offset + i].TimeIndex) { IntroduceRecords(ref handle.Array[handle.Offset + j].OffsetLength, handle.Array[handle.Offset + i].OffsetLength, 1); records.Release(ref handle.Array[handle.Offset + i].OffsetLength); handle.Array[handle.Offset + i] = new CollectionTraceWithHeapIncrement(); } } } } } var position = 0; for (int i = 0; i < handle.Length; i++) { if (!handle.Array[handle.Offset + i].IsEmpty) { var temp = handle.Array[handle.Offset + i]; handle.Array[handle.Offset + i] = new CollectionTraceWithHeapIncrement(); handle.Array[handle.Offset + (position++)] = temp; } } if (handle.Array[handle.Offset].IsEmpty) { increments.Release(ref ol); } offsetLength = ol.offsetLength; } }
public void ReleaseState(ref int keyIndex) { var temp = new OffsetLength(keyIndex); if (!temp.IsEmpty) { increments.Release(ref temp); keyIndex = temp.offsetLength; } ReleaseCache(); }
public void Release(ref OffsetLength ol) { if (!ol.IsEmpty) { var offset = 0; var length = 0; ol.GetOffsetLength(out offset, out length); heaps[length].Release(offset); ol = new OffsetLength(); } }
public Handle <Weighted <S> > EnumerateDifferenceAt(ref OffsetLength ol, int timeIndex) { var handle = increments.Dereference(ol); for (int i = 0; i < handle.Length && !handle.Array[handle.Offset + i].IsEmpty; i++) { if (handle.Array[handle.Offset + i].TimeIndex == timeIndex) { return(records.Dereference(handle.Array[handle.Offset + i].OffsetLength)); } } return(new Handle <Weighted <S> >(null, 0, 0)); }
public Handle<T> Allocate(out OffsetLength ol, int capacity) { var offset = 0; var length = 0; var handle = Allocate(out offset, out length, capacity); for (int i = 0; i < handle.Length; i++) handle.Array[handle.Offset + i] = default(T); ol = new OffsetLength(offset, length); return handle; }
public void EnumerateDifferenceAt(int offsetLength, int timeIndex, NaiadList <Weighted <S> > toFill) { if (toFill.Count == 0) { var temp = new OffsetLength(offsetLength); var weight = 0L; var handle = increments.Dereference(temp); for (int i = 0; i < handle.Length && !handle.Array[handle.Offset + i].IsEmpty; i++) { if (handle.Array[handle.Offset + i].TimeIndex == timeIndex) { weight += handle.Array[handle.Offset + i].Weight; } } if (weight != 0) { toFill.Add(new Weighted <S>(default(S), weight)); } } else { var temp = new OffsetLength(offsetLength); var weight = 0L; var handle = increments.Dereference(temp); for (int i = 0; i < handle.Length && !handle.Array[handle.Offset + i].IsEmpty; i++) { if (handle.Array[handle.Offset + i].TimeIndex == timeIndex) { weight += handle.Array[handle.Offset + i].Weight; } } if (weight != 0) { toFill.Array[0].weight += weight; } if (toFill.Array[0].weight == 0) { toFill.Clear(); } } }
public Handle<T> Dereference(OffsetLength ol) { if (ol.IsEmpty) { return new Handle<T>(null, 0, 0); } else { var offset = 0; var length = 0; ol.GetOffsetLength(out offset, out length); return heaps[length].Dereference(offset); } }
public void EnumerateCollectionAt(int offsetLength, int timeIndex, NaiadList <Weighted <S> > toFill) { if (toFill.Count == 0) { var temp = new OffsetLength(offsetLength); var accum = UpdateAccumulation(ref temp, timeIndex); if (!accum.IsEmpty(isZero)) { toFill.Add(new Weighted <S>(accum.Value, 1)); } } else { throw new NotImplementedException(); } }
public void EnsureStateIsCurrentWRTAdvancedTimes(ref int offsetLength) { var ol = new OffsetLength(offsetLength); if (!ol.IsEmpty) { var handle = increments.Dereference(ol); for (int i = 0; i < handle.Length; i++) { if (handle.Array[handle.Offset + i].Weight != 0) { handle.Array[handle.Offset + i].TimeIndex = UpdateTime(handle.Array[handle.Offset + i].TimeIndex); for (int j = 0; j < i && !handle.Array[handle.Offset + i].IsEmpty(isZero); j++) { if (handle.Array[handle.Offset + j].TimeIndex == handle.Array[handle.Offset + i].TimeIndex) { handle.Array[handle.Offset + j].Add(handle.Array[handle.Offset + i], axpy); handle.Array[handle.Offset + i] = new CollectionTraceWithAggregationIncrement <S>(); } } } } var position = 0; for (int i = 0; i < handle.Length; i++) { if (!handle.Array[handle.Offset + i].IsEmpty(isZero)) { var temp = handle.Array[handle.Offset + i]; handle.Array[handle.Offset + i] = new CollectionTraceWithAggregationIncrement <S>(); handle.Array[handle.Offset + (position++)] = temp; } } if (handle.Array[handle.Offset].IsEmpty(isZero)) { increments.Release(ref ol); } offsetLength = ol.offsetLength; } }
void IntroduceIncrements(ref OffsetLength thisOffsetLength, OffsetLength thatOffsetLength, int scale) { var handle = increments.Dereference(thatOffsetLength); for (int i = 0; i < handle.Length; i++) { if (!handle.Array[handle.Offset + i].IsEmpty) { var recordHandle = records.Dereference(handle.Array[handle.Offset + i].OffsetLength); for (int j = 0; j < recordHandle.Length; j++) { if (recordHandle.Array[recordHandle.Offset + j].weight != 0) { Introduce(ref thisOffsetLength, recordHandle.Array[recordHandle.Offset + j].record, scale * recordHandle.Array[recordHandle.Offset + j].weight, handle.Array[handle.Offset + i].TimeIndex); } } } } }
void Print(OffsetLength ol) { var handle = increments.Dereference(ol); for (int i = 0; i < handle.Length; i++) { if (!handle.Array[handle.Offset + i].IsEmpty) { Console.WriteLine("data at time {0}", handle.Array[handle.Offset + i].TimeIndex); var rHandle = records.Dereference(handle.Array[handle.Offset + i].OffsetLength); for (int j = 0; j < rHandle.Length; j++) { if (rHandle.Array[rHandle.Offset + j].weight != 0) { Console.WriteLine(" {0}", rHandle.Array[rHandle.Offset + j]); } } } } }
public Handle<T> EnsureAllocation(ref OffsetLength ol, int capacity) { if (ol.IsEmpty) { return Allocate(out ol, capacity); } else { var offset = 0; var length = 0; ol.GetOffsetLength(out offset, out length); var handle = EnsureAllocation(ref offset, ref length, capacity); ol = new OffsetLength(offset, length); return handle; } }
void Introduce(ref OffsetLength offsetLength, S element, Int64 weight, int timeIndex) { var handle = EnsureTime(ref offsetLength, timeIndex); var position = 0; while (handle.Array[handle.Offset + position].TimeIndex != timeIndex) { position++; } if (handle.Array[handle.Offset + position].IsEmpty(isZero)) { handle.Array[handle.Offset + position] = new CollectionTraceWithAggregationIncrement <S>(weight, timeIndex, element); } else { var incr = handle.Array[handle.Offset + position]; var result = new CollectionTraceWithAggregationIncrement <S>(incr.Weight + weight, timeIndex, axpy(1, element, incr.Value)); handle.Array[handle.Offset + position] = result; } // if the introduction results in an empty region, we need to clean up if (handle.Array[handle.Offset + position].IsEmpty(isZero)) { // drag everything after it down one for (int i = position + 1; i < handle.Length; i++) { handle.Array[handle.Offset + i - 1] = handle.Array[handle.Offset + i]; } handle.Array[handle.Offset + handle.Length - 1] = new CollectionTraceWithAggregationIncrement <S>(); // if the root element is empty, the list must be empty if (handle.Array[handle.Offset].IsEmpty(isZero)) { increments.Release(ref offsetLength); } } }
public void ZeroState(ref int keyIndex) { var temp = new OffsetLength(keyIndex); if (!temp.IsEmpty) { var handle = increments.Dereference(temp); for (int i = 0; i < handle.Length; i++) { if (!handle.Array[handle.Offset + i].IsEmpty) { records.Release(ref handle.Array[handle.Offset + i].OffsetLength); } } increments.Release(ref temp); keyIndex = temp.offsetLength; } ReleaseCache(); }