using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; using MarketData.MarketDataModel; using MarketData.Helper; using MarketData.DataAccess; using MarketData.Utils; namespace TradeBlotter.Cache { //public class CacheInfo //{ // public CacheInfo() // { // } // public Prices Prices { get; set; } //} public class PriceCache : IDisposable { private Dictionary priceCache = new Dictionary(); private Object thisLock = new Object(); private Thread cacheMonitorThread = null; private bool threadRun = true; private int cacheRefreshAfter = 30000; private static PriceCache priceCacheInstance = null; private PriceCache() { cacheMonitorThread = new Thread(new ThreadStart(ThreadProc)); cacheMonitorThread.Start(); } public static PriceCache GetInstance() { lock (typeof(PriceCache)) { if (null == priceCacheInstance) priceCacheInstance = new PriceCache(); return priceCacheInstance; } } public void Dispose() { lock (thisLock) { threadRun = false; if (null != cacheMonitorThread) { cacheMonitorThread.Join(); } priceCache.Clear(); priceCacheInstance = null; } } public Prices GetPrices(String symbol, int days) { lock (thisLock) { DateTime now = DateTime.Now; Prices prices = null; Price price = null; if (priceCache.ContainsKey(symbol)) prices = priceCache[symbol]; if (null != prices) { if (prices.Count >= days) { Prices priceRange = null; if (prices.Count == days) priceRange = prices; else priceRange = new Prices(prices.GetRange(0, days).ToArray()); return priceRange; } if(prices.Count>0)price = prices[0]; prices = PricingDA.GetPrices(symbol, days); if (null!=prices&&price.Date.Date.Equals(DateTime.Now.Date.Date)&&(prices.Count>0&&prices[0].Date.Date!=price.Date.Date)) prices.Insert(0,price); return prices; } prices = PricingDA.GetPrices(symbol, days); if (null != prices && 0 != prices.Count) priceCache.Add(symbol, prices); return prices; } } public Price GetLatestPrice(String symbol) { lock (thisLock) { DateTime now = DateTime.Now; Price price = null; Prices prices = null; if (priceCache.ContainsKey(symbol)) prices = priceCache[symbol]; if (null!=prices) { if (0 == prices.Count) { price = MarketDataHelper.GetLatestPrice(symbol); if (null != price) prices.Add(price); } else { price = prices[0]; if (price.Date.Date.Equals(now.Date.Date)) return price; price = MarketDataHelper.GetLatestPrice(symbol); if (null != price) prices.Insert(0,price); } return price; } price = MarketDataHelper.GetLatestPrice(symbol); if (null != price) { prices = new Prices(); prices.Add(price); priceCache.Add(symbol, prices); } return price; } } public bool Contains(String symbol) { lock (thisLock) { return priceCache.ContainsKey(symbol); } } private void ThreadProc() { int quantums = 0; int quantumInterval = 500; while (threadRun) { Thread.Sleep(quantumInterval); quantums += quantumInterval; if (quantums > cacheRefreshAfter) { quantums = 0; lock (thisLock) { DateTime now = DateTime.Now; List symbols = new List(priceCache.Keys); foreach (String symbol in symbols) { Prices prices=priceCache[symbol]; if (null ==prices || 0 == prices.Count) continue; Price price = prices[0]; if (price.Date.Date.Equals(now.Date.Date)) { prices.Remove(price); price=MarketDataHelper.GetLatestPrice(symbol); if(null==price)prices.Insert(0,price); } //if (price.Date.Date.Equals(now.Date.Date)) prices.Remove(price); } } } } } } }