Code cleanup.

This commit is contained in:
2026-02-24 12:42:22 -05:00
parent 753e6975ce
commit 6212065262
2 changed files with 49 additions and 67 deletions

View File

@@ -51,18 +51,12 @@ namespace MarketData.Cache
private DateGenerator dateGenerator = new DateGenerator(); private DateGenerator dateGenerator = new DateGenerator();
private static GBPriceCache priceCacheInstance = null; private static GBPriceCache priceCacheInstance = null;
private int cacheRefreshAfter = 120000; // 2 minutes private int cacheRefreshAfter = 120000; // 2 minutes
private SemaphoreSlim fetchSemaphore = new SemaphoreSlim(8); // max 8 concurrent DB fetches private SemaphoreSlim fetchSemaphore = new SemaphoreSlim(8); // max 8 concurrent DB fetches
public IPricingDataAccess PricingDataAccess { get; set; } = new RealPricingDA(); public IPricingDataAccess PricingDataAccess { get; set; } = new RealPricingDA();
protected GBPriceCache() protected GBPriceCache()
{ {
snapshot = new CacheSnapshot( snapshot = new CacheSnapshot(new Dictionary<String, PricesByDate>(), new Dictionary<String, Price>(), new Dictionary<String, bool>());
new Dictionary<String, PricesByDate>(),
new Dictionary<String, Price>(),
new Dictionary<String, bool>());
cacheMonitorThread = new Thread(new ThreadStart(ThreadProc)); cacheMonitorThread = new Thread(new ThreadStart(ThreadProc));
cacheMonitorThread.Start(); cacheMonitorThread.Start();
} }
@@ -71,7 +65,7 @@ namespace MarketData.Cache
{ {
lock (typeof(GBPriceCache)) lock (typeof(GBPriceCache))
{ {
if (priceCacheInstance == null) if (null == priceCacheInstance)
{ {
priceCacheInstance = new GBPriceCache(); priceCacheInstance = new GBPriceCache();
} }
@@ -83,10 +77,7 @@ namespace MarketData.Cache
{ {
lock (thisLock) lock (thisLock)
{ {
snapshot = new CacheSnapshot( snapshot = new CacheSnapshot(new Dictionary<String, PricesByDate>(), new Dictionary<String, Price>(), new Dictionary<String, bool>());
new Dictionary<String, PricesByDate>(),
new Dictionary<String, Price>(),
new Dictionary<String, bool>());
} }
} }
@@ -94,16 +85,14 @@ namespace MarketData.Cache
{ {
lock (thisLock) lock (thisLock)
{ {
if (priceCacheInstance == null || !threadRun) return; if (null == priceCacheInstance || !threadRun) return;
threadRun = false; threadRun = false;
if (null != cacheMonitorThread)
if (cacheMonitorThread != null)
{ {
MDTrace.WriteLine(LogLevel.DEBUG, "[GBPriceCache:Dispose] Joining monitor thread..."); MDTrace.WriteLine(LogLevel.DEBUG, "[GBPriceCache:Dispose] Joining monitor thread...");
cacheMonitorThread.Join(5000); cacheMonitorThread.Join(5000);
cacheMonitorThread = null; cacheMonitorThread = null;
} }
priceCacheInstance = null; priceCacheInstance = null;
} }
} }
@@ -118,26 +107,19 @@ namespace MarketData.Cache
String symbol = entry.Key; String symbol = entry.Key;
PricesByDate filteredPrices = new PricesByDate(); PricesByDate filteredPrices = new PricesByDate();
PricesByDate existingPrices = entry.Value; PricesByDate existingPrices = entry.Value;
foreach (KeyValuePair<DateTime, Price> kvp in existingPrices)
foreach (KeyValuePair<DateTime, Price> kv 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) if (filteredPrices.Count > 0)
{ {
newPriceCache.Add(symbol, filteredPrices); newPriceCache.Add(symbol, filteredPrices);
} }
} }
UpdateSnapshot(newPriceCache, snapshot.RealTimePriceCache, snapshot.NullCache);
UpdateSnapshot(
newPriceCache,
snapshot.RealTimePriceCache,
snapshot.NullCache);
if (collect) GC.Collect(); if (collect) GC.Collect();
} }
} }
@@ -145,12 +127,10 @@ namespace MarketData.Cache
public Price GetPriceOrLatestAvailable(String symbol, DateTime date) public Price GetPriceOrLatestAvailable(String symbol, DateTime date)
{ {
Price price = GetPrice(symbol, date); Price price = GetPrice(symbol, date);
if (price != null) return price; if (null != price) return price;
DateTime latestPricingDate = PricingDataAccess.GetLatestDateOnOrBefore(symbol, date); DateTime latestPricingDate = PricingDataAccess.GetLatestDateOnOrBefore(symbol, date);
price = GetPrice(symbol, latestPricingDate); price = GetPrice(symbol, latestPricingDate);
if (price != null) return price; if (null != price) return price;
fetchSemaphore.Wait(); fetchSemaphore.Wait();
try try
{ {
@@ -160,8 +140,7 @@ namespace MarketData.Cache
{ {
fetchSemaphore.Release(); fetchSemaphore.Release();
} }
if (null !=price) AddPrice(price);
if (price != null) AddPrice(price);
return price; return price;
} }
@@ -173,7 +152,7 @@ namespace MarketData.Cache
} }
Price price = MarketDataHelper.GetLatestPrice(symbol); Price price = MarketDataHelper.GetLatestPrice(symbol);
if (price != null) if (null != price)
{ {
Dictionary<String, Price> newRealtime = new Dictionary<String, Price>(snapshot.RealTimePriceCache); Dictionary<String, Price> newRealtime = new Dictionary<String, Price>(snapshot.RealTimePriceCache);
newRealtime.Add(symbol, price); newRealtime.Add(symbol, price);
@@ -192,7 +171,6 @@ namespace MarketData.Cache
{ {
return null; return null;
} }
fetchSemaphore.Wait(); fetchSemaphore.Wait();
Price price; Price price;
try try
@@ -203,8 +181,7 @@ namespace MarketData.Cache
{ {
fetchSemaphore.Release(); fetchSemaphore.Release();
} }
if (null ==price)
if (price == null)
{ {
Dictionary<String, bool> newNullCache = new Dictionary<String, bool>(snapshot.NullCache); Dictionary<String, bool> newNullCache = new Dictionary<String, bool>(snapshot.NullCache);
newNullCache.Add(key, true); newNullCache.Add(key, true);
@@ -214,7 +191,6 @@ namespace MarketData.Cache
AddPrice(price); AddPrice(price);
} }
if (!snapshot.PriceCache.ContainsKey(symbol)) return null; if (!snapshot.PriceCache.ContainsKey(symbol)) return null;
PricesByDate pricesByDate = snapshot.PriceCache[symbol]; PricesByDate pricesByDate = snapshot.PriceCache[symbol];
if (!pricesByDate.ContainsKey(date)) return null; if (!pricesByDate.ContainsKey(date)) return null;
@@ -224,24 +200,20 @@ namespace MarketData.Cache
public Prices GetPrices(String symbol, DateTime earlierDate, DateTime laterDate) public Prices GetPrices(String symbol, DateTime earlierDate, DateTime laterDate)
{ {
DateGenerator localDateGenerator = new DateGenerator(); DateGenerator localDateGenerator = new DateGenerator();
if (laterDate < earlierDate) if (laterDate < earlierDate)
{ {
DateTime tempDate = earlierDate; DateTime tempDate = earlierDate;
earlierDate = laterDate; earlierDate = laterDate;
laterDate = tempDate; laterDate = tempDate;
} }
List<DateTime> datesList = localDateGenerator.GenerateHistoricalDates(earlierDate, laterDate); List<DateTime> datesList = localDateGenerator.GenerateHistoricalDates(earlierDate, laterDate);
datesList = datesList.Where(x => x >= earlierDate).ToList(); datesList = datesList.Where(x => x >= earlierDate).ToList();
return GetPrices(symbol, laterDate, datesList.Count); return GetPrices(symbol, laterDate, datesList.Count);
} }
public Prices GetPrices(String symbol, DateTime startDate, int dayCount) public Prices GetPrices(String symbol, DateTime startDate, int dayCount)
{ {
List<DateTime> historicalDates = dateGenerator.GenerateHistoricalDates(startDate, dayCount + 60); List<DateTime> historicalDates = dateGenerator.GenerateHistoricalDates(startDate, dayCount + 60);
List<DateTime> missingDates = new List<DateTime>(); List<DateTime> missingDates = new List<DateTime>();
foreach (DateTime historicalDate in historicalDates) foreach (DateTime historicalDate in historicalDates)
{ {
@@ -254,7 +226,6 @@ namespace MarketData.Cache
} }
} }
} }
if (missingDates.Count > 0) if (missingDates.Count > 0)
{ {
DateTime minDate = missingDates.Min(); DateTime minDate = missingDates.Min();
@@ -292,7 +263,7 @@ namespace MarketData.Cache
private void AddPrice(Price price) private void AddPrice(Price price)
{ {
if (price == null) return; if (null == price) return;
lock (thisLock) lock (thisLock)
{ {
@@ -331,8 +302,8 @@ namespace MarketData.Cache
while (threadRun) while (threadRun)
{ {
Thread.Sleep(quantumInterval); Thread.Sleep(quantumInterval);
if(!threadRun)break;
quantums += quantumInterval; quantums += quantumInterval;
if (quantums > cacheRefreshAfter) if (quantums > cacheRefreshAfter)
{ {
quantums = 0; quantums = 0;
@@ -344,10 +315,7 @@ namespace MarketData.Cache
} }
} }
private void UpdateSnapshot( private void UpdateSnapshot(Dictionary<String, PricesByDate> newPriceCache,Dictionary<String, Price> newRealtimePriceCache, Dictionary<String, bool> newNullCache)
Dictionary<String, PricesByDate> newPriceCache,
Dictionary<String, Price> newRealtimePriceCache,
Dictionary<String, bool> newNullCache)
{ {
snapshot = new CacheSnapshot(newPriceCache, newRealtimePriceCache, newNullCache); snapshot = new CacheSnapshot(newPriceCache, newRealtimePriceCache, newNullCache);
} }

View File

@@ -2,6 +2,11 @@
using MarketData.Utils; using MarketData.Utils;
using MarketData.DataAccess; using MarketData.DataAccess;
using System.Collections.Concurrent; using System.Collections.Concurrent;
using System.Threading;
using System.Collections.Generic;
using System;
using System.Threading.Tasks;
using System.Linq;
namespace MarketData.Cache namespace MarketData.Cache
{ {
@@ -109,9 +114,11 @@ namespace MarketData.Cache
Parallel.ForEach(symbols, new ParallelOptions { MaxDegreeOfParallelism = 8 }, symbol => 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); Prices prices = PricingDA.GetPrices(symbol, cachedMax);
if (prices != null) fullReloads[symbol] = prices.GetPricesByDate(); if (prices != null) fullReloads[symbol] = prices.GetPricesByDate();
@@ -128,7 +135,7 @@ namespace MarketData.Cache
{ {
latestDate = latestDateFromDb; 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]) 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]) 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)) if (pricesByDate.ContainsKey(kvp.Value.Date))
pricesByDate.Remove(kvp.Value.Date); pricesByDate.Remove(kvp.Value.Date);
pricesByDate.Add(kvp.Value.Date, kvp.Value); pricesByDate.Add(kvp.Value.Date, kvp.Value);
@@ -194,9 +200,9 @@ namespace MarketData.Cache
lock (thisLock) 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); Add(price);
} }
@@ -238,7 +244,7 @@ namespace MarketData.Cache
lock (thisLock) lock (thisLock)
{ {
foreach (var kvp in fetchedPrices) foreach (KeyValuePair<string, Price> kvp in fetchedPrices)
{ {
Add(kvp.Value); Add(kvp.Value);
} }
@@ -251,14 +257,15 @@ namespace MarketData.Cache
lock (thisLock) lock (thisLock)
{ {
if (!priceCache.TryGetValue(price.Symbol, out var pricesByDate)) PricesByDate pricesByDate;
if (!priceCache.TryGetValue(price.Symbol, out pricesByDate))
{ {
pricesByDate = new PricesByDate(); pricesByDate = new PricesByDate();
priceCache[price.Symbol] = pricesByDate; priceCache[price.Symbol] = pricesByDate;
} }
if (!pricesByDate.ContainsKey(price.Date)) 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) 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; return Utility.Epoch;
} }
@@ -279,7 +287,7 @@ namespace MarketData.Cache
{ {
lock (thisLock) lock (thisLock)
{ {
foreach (var kvp in priceCache) foreach (KeyValuePair<string, PricesByDate> kvp in priceCache)
{ {
kvp.Value.Remove(date); kvp.Value.Remove(date);
} }
@@ -290,7 +298,8 @@ namespace MarketData.Cache
{ {
lock (thisLock) 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(); DateGenerator dateGenerator = new DateGenerator();
List<DateTime> historicalDates = dateGenerator.GenerateHistoricalDates(endDate, dayCount); List<DateTime> historicalDates = dateGenerator.GenerateHistoricalDates(endDate, dayCount);
@@ -312,8 +321,11 @@ namespace MarketData.Cache
{ {
lock (thisLock) lock (thisLock)
{ {
if (!priceCache.TryGetValue(symbol, out var pricesByDate)) return null; PricesByDate pricesByDate;
return pricesByDate.TryGetValue(date, out var price) ? price : null; 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) 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); return pricesByDate.ContainsKey(date);
} }
} }
@@ -334,7 +347,8 @@ namespace MarketData.Cache
{ {
foreach (string symbol in symbols) 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; return false;
} }
@@ -356,7 +370,7 @@ namespace MarketData.Cache
lock (thisLock) lock (thisLock)
{ {
long count = 0; long count = 0;
foreach (var pricesByDate in priceCache.Values) foreach (PricesByDate pricesByDate in priceCache.Values)
{ {
count += pricesByDate.Count; count += pricesByDate.Count;
} }