⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 timeseriesimpl.cs

📁 Perst开源实时数据库
💻 CS
📖 第 1 页 / 共 2 页
字号:
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 + -