📄 timeseriesimpl.cs
字号:
namespace Perst.Impl
{
using System;
#if USE_GENERICS
using System.Collections.Generic;
#endif
using System.Collections;
using System.Reflection;
using System.Diagnostics;
using Perst;
#if USE_GENERICS
class TimeSeriesImpl<T> : PersistentResource, TimeSeries<T> where T:TimeSeriesTick
#else
class TimeSeriesImpl : PersistentCollection, TimeSeries
#endif
{
#if USE_GENERICS
public virtual bool IsSynchronized
{
get
{
return true;
}
}
public virtual object SyncRoot
{
get
{
return this;
}
}
public void Clear()
{
foreach (TimeSeriesBlock block in index)
{
block.Deallocate();
}
index.Clear();
}
public virtual void CopyTo(T[] dst, int i)
{
foreach (object o in this)
{
dst.SetValue(o, i++);
}
}
public virtual bool IsReadOnly
{
get
{
return false;
}
}
public bool Contains(T obj)
{
return Contains(new DateTime(obj.Time));
}
public bool Remove(T obj)
{
DateTime t = new DateTime(obj.Time);
return Remove(t, t) != 0;
}
public class TimeSeriesBlock : Persistent
{
public long timestamp;
public int used;
public T[] Ticks;
public T this[int i]
{
get
{
return Ticks[i];
}
set
{
Ticks[i] = value;
}
}
public TimeSeriesBlock(int size) {
Ticks = new T[size];
}
TimeSeriesBlock() {}
}
#endif
#if USE_GENERICS
public void Add(T tick)
#else
public void Add(TimeSeriesTick tick)
#endif
{
long time = tick.Time;
foreach (TimeSeriesBlock block in index.Range(time - maxBlockTimeInterval, time, IterationOrder.DescentOrder)) {
insertInBlock(block, tick);
return;
}
addNewBlock(tick);
}
#if USE_GENERICS
class TimeSeriesEnumerator : IEnumerator<T>, IEnumerable<T>, IEnumerator, IEnumerable
#else
class TimeSeriesEnumerator : IEnumerator, IEnumerable
#endif
{
#if USE_GENERICS
internal TimeSeriesEnumerator(IEnumerator<TimeSeriesBlock> blockIterator, long from, long till)
#else
internal TimeSeriesEnumerator(IEnumerator blockIterator, long from, long till)
#endif
{
this.till = till;
this.from = from;
this.blockIterator = blockIterator;
Reset();
}
#if USE_GENERICS
IEnumerator IEnumerable.GetEnumerator()
{
return this;
}
public IEnumerator<T> GetEnumerator()
#else
public IEnumerator GetEnumerator()
#endif
{
return this;
}
public void Reset()
{
#if !USE_GENERICS
if (resetNeeded)
{
blockIterator.Reset();
}
resetNeeded = true;
#endif
hasCurrent = false;
pos = -1;
while (blockIterator.MoveNext())
{
TimeSeriesBlock block = (TimeSeriesBlock)blockIterator.Current;
int n = block.used;
int l = 0, r = n;
while (l < r)
{
int i = (l+r) >> 1;
if (from > block[i].Time)
{
l = i+1;
}
else
{
r = i;
}
}
Debug.Assert(l == r && (l == n || block[l].Time >= from));
if (l < n)
{
pos = l;
currBlock = block;
return;
}
}
}
public void Dispose() {}
public bool MoveNext()
{
if (hasCurrent)
{
hasCurrent = false;
if (++pos == currBlock.used)
{
if (blockIterator.MoveNext())
{
currBlock = (TimeSeriesBlock)blockIterator.Current;
pos = 0;
}
else
{
pos = -1;
return false;
}
}
}
else if (pos < 0)
{
return false;
}
if (currBlock[pos].Time > till)
{
pos = -1;
return false;
}
hasCurrent = true;
return true;
}
#if USE_GENERICS
object IEnumerator.Current
{
get
{
return getCurrent();
}
}
public virtual T Current
{
get
{
return (T)getCurrent();
}
}
#else
public virtual object Current
{
get
{
return getCurrent();
}
}
#endif
private object getCurrent()
{
if (!hasCurrent)
{
throw new InvalidOperationException();
}
return currBlock[pos];
}
#if USE_GENERICS
private IEnumerator<TimeSeriesBlock> blockIterator;
#else
private IEnumerator blockIterator;
private bool resetNeeded;
#endif
private bool hasCurrent;
private TimeSeriesBlock currBlock;
private int pos;
private long from;
private long till;
}
#if USE_GENERICS
class TimeSeriesReverseEnumerator : IEnumerator<T>, IEnumerable<T>, IEnumerator, IEnumerable
#else
class TimeSeriesReverseEnumerator : IEnumerator, IEnumerable
#endif
{
#if USE_GENERICS
internal TimeSeriesReverseEnumerator(IEnumerator<TimeSeriesBlock> blockIterator, long from, long till)
#else
internal TimeSeriesReverseEnumerator(IEnumerator blockIterator, long from, long till)
#endif
{
this.till = till;
this.from = from;
this.blockIterator = blockIterator;
Reset();
}
#if USE_GENERICS
IEnumerator IEnumerable.GetEnumerator()
{
return this;
}
public IEnumerator<T> GetEnumerator()
#else
public IEnumerator GetEnumerator()
#endif
{
return this;
}
public void Reset()
{
#if !USE_GENERICS
if (resetNeeded)
{
blockIterator.Reset();
}
resetNeeded = true;
#endif
hasCurrent = false;
pos = -1;
while (blockIterator.MoveNext())
{
TimeSeriesBlock block = (TimeSeriesBlock)blockIterator.Current;
int n = block.used;
int l = 0, r = n;
while (l < r)
{
int i = (l+r) >> 1;
if (till >= block[i].Time)
{
l = i+1;
}
else
{
r = i;
}
}
Debug.Assert(l == r && (l == n || block[l].Time > till));
if (l > 0)
{
pos = l-1;
currBlock = block;
return;
}
}
}
public void Dispose() {}
public bool MoveNext()
{
if (hasCurrent)
{
hasCurrent = false;
if (--pos < 0)
{
if (blockIterator.MoveNext())
{
currBlock = (TimeSeriesBlock)blockIterator.Current;
pos = currBlock.used-1;
}
else
{
pos = -1;
return false;
}
}
}
else if (pos < 0)
{
return false;
}
if (currBlock[pos].Time < from)
{
pos = -1;
return false;
}
hasCurrent = true;
return true;
}
#if USE_GENERICS
object IEnumerator.Current
{
get
{
return getCurrent();
}
}
public virtual T Current
{
get
{
return (T)getCurrent();
}
}
#else
public virtual object Current
{
get
{
return getCurrent();
}
}
#endif
private object getCurrent()
{
if (!hasCurrent)
{
throw new InvalidOperationException();
}
return currBlock[pos];
}
#if USE_GENERICS
private IEnumerator<TimeSeriesBlock> blockIterator;
#else
private IEnumerator blockIterator;
private bool resetNeeded;
#endif
private bool hasCurrent;
private TimeSeriesBlock currBlock;
private int pos;
private long from;
private long till;
}
#if USE_GENERICS
IEnumerator IEnumerable.GetEnumerator()
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -