Code cleanup.
This commit is contained in:
@@ -51,18 +51,12 @@ namespace MarketData.Cache
|
||||
private DateGenerator dateGenerator = new DateGenerator();
|
||||
private static GBPriceCache priceCacheInstance = null;
|
||||
private int cacheRefreshAfter = 120000; // 2 minutes
|
||||
|
||||
private SemaphoreSlim fetchSemaphore = new SemaphoreSlim(8); // max 8 concurrent DB fetches
|
||||
|
||||
public IPricingDataAccess PricingDataAccess { get; set; } = new RealPricingDA();
|
||||
|
||||
protected GBPriceCache()
|
||||
{
|
||||
snapshot = new CacheSnapshot(
|
||||
new Dictionary<String, PricesByDate>(),
|
||||
new Dictionary<String, Price>(),
|
||||
new Dictionary<String, bool>());
|
||||
|
||||
snapshot = new CacheSnapshot(new Dictionary<String, PricesByDate>(), new Dictionary<String, Price>(), new Dictionary<String, bool>());
|
||||
cacheMonitorThread = new Thread(new ThreadStart(ThreadProc));
|
||||
cacheMonitorThread.Start();
|
||||
}
|
||||
@@ -71,7 +65,7 @@ namespace MarketData.Cache
|
||||
{
|
||||
lock (typeof(GBPriceCache))
|
||||
{
|
||||
if (priceCacheInstance == null)
|
||||
if (null == priceCacheInstance)
|
||||
{
|
||||
priceCacheInstance = new GBPriceCache();
|
||||
}
|
||||
@@ -83,10 +77,7 @@ namespace MarketData.Cache
|
||||
{
|
||||
lock (thisLock)
|
||||
{
|
||||
snapshot = new CacheSnapshot(
|
||||
new Dictionary<String, PricesByDate>(),
|
||||
new Dictionary<String, Price>(),
|
||||
new Dictionary<String, bool>());
|
||||
snapshot = new CacheSnapshot(new Dictionary<String, PricesByDate>(), new Dictionary<String, Price>(), new Dictionary<String, bool>());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -94,16 +85,14 @@ namespace MarketData.Cache
|
||||
{
|
||||
lock (thisLock)
|
||||
{
|
||||
if (priceCacheInstance == null || !threadRun) return;
|
||||
if (null == priceCacheInstance || !threadRun) return;
|
||||
threadRun = false;
|
||||
|
||||
if (cacheMonitorThread != null)
|
||||
if (null != cacheMonitorThread)
|
||||
{
|
||||
MDTrace.WriteLine(LogLevel.DEBUG, "[GBPriceCache:Dispose] Joining monitor thread...");
|
||||
cacheMonitorThread.Join(5000);
|
||||
cacheMonitorThread = null;
|
||||
}
|
||||
|
||||
priceCacheInstance = null;
|
||||
}
|
||||
}
|
||||
@@ -118,26 +107,19 @@ namespace MarketData.Cache
|
||||
String symbol = entry.Key;
|
||||
PricesByDate filteredPrices = new PricesByDate();
|
||||
PricesByDate existingPrices = entry.Value;
|
||||
|
||||
foreach (KeyValuePair<DateTime, Price> kv in existingPrices)
|
||||
foreach (KeyValuePair<DateTime, Price> kvp in existingPrices)
|
||||
{
|
||||
if (kv.Key >= onOrBeforeDate)
|
||||
if (kvp.Key >= onOrBeforeDate)
|
||||
{
|
||||
filteredPrices.Add(kv.Key, kv.Value);
|
||||
filteredPrices.Add(kvp.Key, kvp.Value);
|
||||
}
|
||||
}
|
||||
|
||||
if (filteredPrices.Count > 0)
|
||||
{
|
||||
newPriceCache.Add(symbol, filteredPrices);
|
||||
}
|
||||
}
|
||||
|
||||
UpdateSnapshot(
|
||||
newPriceCache,
|
||||
snapshot.RealTimePriceCache,
|
||||
snapshot.NullCache);
|
||||
|
||||
UpdateSnapshot(newPriceCache, snapshot.RealTimePriceCache, snapshot.NullCache);
|
||||
if (collect) GC.Collect();
|
||||
}
|
||||
}
|
||||
@@ -145,12 +127,10 @@ namespace MarketData.Cache
|
||||
public Price GetPriceOrLatestAvailable(String symbol, DateTime date)
|
||||
{
|
||||
Price price = GetPrice(symbol, date);
|
||||
if (price != null) return price;
|
||||
|
||||
if (null != price) return price;
|
||||
DateTime latestPricingDate = PricingDataAccess.GetLatestDateOnOrBefore(symbol, date);
|
||||
price = GetPrice(symbol, latestPricingDate);
|
||||
if (price != null) return price;
|
||||
|
||||
if (null != price) return price;
|
||||
fetchSemaphore.Wait();
|
||||
try
|
||||
{
|
||||
@@ -160,8 +140,7 @@ namespace MarketData.Cache
|
||||
{
|
||||
fetchSemaphore.Release();
|
||||
}
|
||||
|
||||
if (price != null) AddPrice(price);
|
||||
if (null !=price) AddPrice(price);
|
||||
return price;
|
||||
}
|
||||
|
||||
@@ -173,7 +152,7 @@ namespace MarketData.Cache
|
||||
}
|
||||
|
||||
Price price = MarketDataHelper.GetLatestPrice(symbol);
|
||||
if (price != null)
|
||||
if (null != price)
|
||||
{
|
||||
Dictionary<String, Price> newRealtime = new Dictionary<String, Price>(snapshot.RealTimePriceCache);
|
||||
newRealtime.Add(symbol, price);
|
||||
@@ -192,7 +171,6 @@ namespace MarketData.Cache
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
fetchSemaphore.Wait();
|
||||
Price price;
|
||||
try
|
||||
@@ -203,8 +181,7 @@ namespace MarketData.Cache
|
||||
{
|
||||
fetchSemaphore.Release();
|
||||
}
|
||||
|
||||
if (price == null)
|
||||
if (null ==price)
|
||||
{
|
||||
Dictionary<String, bool> newNullCache = new Dictionary<String, bool>(snapshot.NullCache);
|
||||
newNullCache.Add(key, true);
|
||||
@@ -214,7 +191,6 @@ namespace MarketData.Cache
|
||||
|
||||
AddPrice(price);
|
||||
}
|
||||
|
||||
if (!snapshot.PriceCache.ContainsKey(symbol)) return null;
|
||||
PricesByDate pricesByDate = snapshot.PriceCache[symbol];
|
||||
if (!pricesByDate.ContainsKey(date)) return null;
|
||||
@@ -224,24 +200,20 @@ namespace MarketData.Cache
|
||||
public Prices GetPrices(String symbol, DateTime earlierDate, DateTime laterDate)
|
||||
{
|
||||
DateGenerator localDateGenerator = new DateGenerator();
|
||||
|
||||
if (laterDate < earlierDate)
|
||||
{
|
||||
DateTime tempDate = earlierDate;
|
||||
earlierDate = laterDate;
|
||||
laterDate = tempDate;
|
||||
}
|
||||
|
||||
List<DateTime> datesList = localDateGenerator.GenerateHistoricalDates(earlierDate, laterDate);
|
||||
datesList = datesList.Where(x => x >= earlierDate).ToList();
|
||||
|
||||
return GetPrices(symbol, laterDate, datesList.Count);
|
||||
}
|
||||
|
||||
public Prices GetPrices(String symbol, DateTime startDate, int dayCount)
|
||||
{
|
||||
List<DateTime> historicalDates = dateGenerator.GenerateHistoricalDates(startDate, dayCount + 60);
|
||||
|
||||
List<DateTime> missingDates = new List<DateTime>();
|
||||
foreach (DateTime historicalDate in historicalDates)
|
||||
{
|
||||
@@ -254,7 +226,6 @@ namespace MarketData.Cache
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (missingDates.Count > 0)
|
||||
{
|
||||
DateTime minDate = missingDates.Min();
|
||||
@@ -292,7 +263,7 @@ namespace MarketData.Cache
|
||||
|
||||
private void AddPrice(Price price)
|
||||
{
|
||||
if (price == null) return;
|
||||
if (null == price) return;
|
||||
|
||||
lock (thisLock)
|
||||
{
|
||||
@@ -331,8 +302,8 @@ namespace MarketData.Cache
|
||||
while (threadRun)
|
||||
{
|
||||
Thread.Sleep(quantumInterval);
|
||||
if(!threadRun)break;
|
||||
quantums += quantumInterval;
|
||||
|
||||
if (quantums > cacheRefreshAfter)
|
||||
{
|
||||
quantums = 0;
|
||||
@@ -344,10 +315,7 @@ namespace MarketData.Cache
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateSnapshot(
|
||||
Dictionary<String, PricesByDate> newPriceCache,
|
||||
Dictionary<String, Price> newRealtimePriceCache,
|
||||
Dictionary<String, bool> newNullCache)
|
||||
private void UpdateSnapshot(Dictionary<String, PricesByDate> newPriceCache,Dictionary<String, Price> newRealtimePriceCache, Dictionary<String, bool> newNullCache)
|
||||
{
|
||||
snapshot = new CacheSnapshot(newPriceCache, newRealtimePriceCache, newNullCache);
|
||||
}
|
||||
|
||||
@@ -2,6 +2,11 @@
|
||||
using MarketData.Utils;
|
||||
using MarketData.DataAccess;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Threading;
|
||||
using System.Collections.Generic;
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using System.Linq;
|
||||
|
||||
namespace MarketData.Cache
|
||||
{
|
||||
@@ -109,9 +114,11 @@ namespace MarketData.Cache
|
||||
|
||||
Parallel.ForEach(symbols, new ParallelOptions { MaxDegreeOfParallelism = 8 }, symbol =>
|
||||
{
|
||||
if (!currentMaxDates.TryGetValue(symbol, out var cachedMax)) return;
|
||||
DateTime cachedMax;
|
||||
if (!currentMaxDates.TryGetValue(symbol, out cachedMax)) return;
|
||||
|
||||
if (maxDbDates.TryGetValue(symbol, out var dbMax) && dbMax.Date != cachedMax.Date)
|
||||
DateTime dbMax;
|
||||
if (maxDbDates.TryGetValue(symbol, out dbMax) && dbMax.Date != cachedMax.Date)
|
||||
{
|
||||
Prices prices = PricingDA.GetPrices(symbol, cachedMax);
|
||||
if (prices != null) fullReloads[symbol] = prices.GetPricesByDate();
|
||||
@@ -128,7 +135,7 @@ namespace MarketData.Cache
|
||||
{
|
||||
latestDate = latestDateFromDb;
|
||||
|
||||
foreach (var kvp in fullReloads)
|
||||
foreach (KeyValuePair<string, PricesByDate> kvp in fullReloads)
|
||||
{
|
||||
if (priceCache.TryGetValue(kvp.Key, out PricesByDate existing) && existing.MaxDate == currentMaxDates[kvp.Key])
|
||||
{
|
||||
@@ -136,11 +143,10 @@ namespace MarketData.Cache
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var kvp in singleUpdates)
|
||||
foreach (KeyValuePair<string, Price> kvp in singleUpdates)
|
||||
{
|
||||
if (priceCache.TryGetValue(kvp.Key, out PricesByDate pricesByDate) && pricesByDate.MaxDate == currentMaxDates[kvp.Key])
|
||||
{
|
||||
// Remove the old price (if any) and add the new price properly
|
||||
if (pricesByDate.ContainsKey(kvp.Value.Date))
|
||||
pricesByDate.Remove(kvp.Value.Date);
|
||||
pricesByDate.Add(kvp.Value.Date, kvp.Value);
|
||||
@@ -194,9 +200,9 @@ namespace MarketData.Cache
|
||||
|
||||
lock (thisLock)
|
||||
{
|
||||
foreach (var kvp in fetchedPrices)
|
||||
foreach (KeyValuePair<string, Prices> kvp in fetchedPrices)
|
||||
{
|
||||
foreach (var price in kvp.Value)
|
||||
foreach (Price price in kvp.Value)
|
||||
{
|
||||
Add(price);
|
||||
}
|
||||
@@ -238,7 +244,7 @@ namespace MarketData.Cache
|
||||
|
||||
lock (thisLock)
|
||||
{
|
||||
foreach (var kvp in fetchedPrices)
|
||||
foreach (KeyValuePair<string, Price> kvp in fetchedPrices)
|
||||
{
|
||||
Add(kvp.Value);
|
||||
}
|
||||
@@ -251,14 +257,15 @@ namespace MarketData.Cache
|
||||
|
||||
lock (thisLock)
|
||||
{
|
||||
if (!priceCache.TryGetValue(price.Symbol, out var pricesByDate))
|
||||
PricesByDate pricesByDate;
|
||||
if (!priceCache.TryGetValue(price.Symbol, out pricesByDate))
|
||||
{
|
||||
pricesByDate = new PricesByDate();
|
||||
priceCache[price.Symbol] = pricesByDate;
|
||||
}
|
||||
if (!pricesByDate.ContainsKey(price.Date))
|
||||
{
|
||||
pricesByDate.Add(price.Date, price); // must use Add() to update MinDate/MaxDate
|
||||
pricesByDate.Add(price.Date, price);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -267,7 +274,8 @@ namespace MarketData.Cache
|
||||
{
|
||||
lock (thisLock)
|
||||
{
|
||||
if (!priceCache.TryGetValue(symbol, out var symbolPrices) || symbolPrices.Count == 0)
|
||||
PricesByDate symbolPrices;
|
||||
if (!priceCache.TryGetValue(symbol, out symbolPrices) || symbolPrices.Count == 0)
|
||||
{
|
||||
return Utility.Epoch;
|
||||
}
|
||||
@@ -279,7 +287,7 @@ namespace MarketData.Cache
|
||||
{
|
||||
lock (thisLock)
|
||||
{
|
||||
foreach (var kvp in priceCache)
|
||||
foreach (KeyValuePair<string, PricesByDate> kvp in priceCache)
|
||||
{
|
||||
kvp.Value.Remove(date);
|
||||
}
|
||||
@@ -290,7 +298,8 @@ namespace MarketData.Cache
|
||||
{
|
||||
lock (thisLock)
|
||||
{
|
||||
if (!priceCache.TryGetValue(symbol, out var pricesByDate)) return new Prices();
|
||||
PricesByDate pricesByDate;
|
||||
if (!priceCache.TryGetValue(symbol, out pricesByDate)) return new Prices();
|
||||
|
||||
DateGenerator dateGenerator = new DateGenerator();
|
||||
List<DateTime> historicalDates = dateGenerator.GenerateHistoricalDates(endDate, dayCount);
|
||||
@@ -312,8 +321,11 @@ namespace MarketData.Cache
|
||||
{
|
||||
lock (thisLock)
|
||||
{
|
||||
if (!priceCache.TryGetValue(symbol, out var pricesByDate)) return null;
|
||||
return pricesByDate.TryGetValue(date, out var price) ? price : null;
|
||||
PricesByDate pricesByDate;
|
||||
if (!priceCache.TryGetValue(symbol, out pricesByDate)) return null;
|
||||
|
||||
Price price;
|
||||
return pricesByDate.TryGetValue(date, out price) ? price : null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -321,7 +333,8 @@ namespace MarketData.Cache
|
||||
{
|
||||
lock (thisLock)
|
||||
{
|
||||
if (!priceCache.TryGetValue(symbol, out var pricesByDate)) return false;
|
||||
PricesByDate pricesByDate;
|
||||
if (!priceCache.TryGetValue(symbol, out pricesByDate)) return false;
|
||||
return pricesByDate.ContainsKey(date);
|
||||
}
|
||||
}
|
||||
@@ -334,7 +347,8 @@ namespace MarketData.Cache
|
||||
{
|
||||
foreach (string symbol in symbols)
|
||||
{
|
||||
if (!priceCache.TryGetValue(symbol, out var pricesByDate) || !pricesByDate.ContainsKey(date))
|
||||
PricesByDate pricesByDate;
|
||||
if (!priceCache.TryGetValue(symbol, out pricesByDate) || !pricesByDate.ContainsKey(date))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@@ -356,7 +370,7 @@ namespace MarketData.Cache
|
||||
lock (thisLock)
|
||||
{
|
||||
long count = 0;
|
||||
foreach (var pricesByDate in priceCache.Values)
|
||||
foreach (PricesByDate pricesByDate in priceCache.Values)
|
||||
{
|
||||
count += pricesByDate.Count;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user