Esempio n. 1
0
        public LruProjectionCache(int capacity, TimeSpan minimumRetention, TimeSpan maximumRetention, Func <TProjection, TKey> getKey, Func <DateTime> getUtcNow)
        {
            if (capacity < 1)
            {
                throw new ArgumentOutOfRangeException(nameof(capacity));
            }

            if (minimumRetention < TimeSpan.Zero)
            {
                throw new ArgumentOutOfRangeException(nameof(minimumRetention));
            }

            if (maximumRetention < TimeSpan.Zero)
            {
                throw new ArgumentOutOfRangeException(nameof(maximumRetention));
            }

            if (minimumRetention > maximumRetention)
            {
                throw new ArgumentException("Minimum retention is greater than maximum retention.");
            }

            if (getUtcNow == null)
            {
                throw new ArgumentNullException(nameof(getUtcNow));
            }

            cache = new FluidCache <TProjection>(capacity, minimumRetention, maximumRetention, () => getUtcNow());
            index = cache.AddIndex("projections", projection => getKey(projection));
        }
Esempio n. 2
0
        public WikipediaApi(IHttpClientFactory client)
        {
            _client = client.CreateClient();

            _cache        = new FluidCache <Tuple <string, IReadOnlyList <IDefinition> > >(1024, TimeSpan.FromMinutes(5), TimeSpan.FromDays(1), () => DateTime.UtcNow);
            _bySearchTerm = _cache.AddIndex("bySearchTerm", a => a.Item1);
        }
Esempio n. 3
0
        public void When_scenario_it_should_behavior()
        {
            //-----------------------------------------------------------------------------------------------------------
            // Arrange
            //-----------------------------------------------------------------------------------------------------------
            var cache = new FluidCache <string>(1000, TimeSpan.FromSeconds(10), TimeSpan.FromSeconds(10), () => DateTime.Now, null);

            cache.AddIndex("index", v => int.Parse(v));

            //-----------------------------------------------------------------------------------------------------------
            // Act
            //-----------------------------------------------------------------------------------------------------------
//            Parallel.For(0, 100000, _ =>
//            {
//                int key = new Random().Next(0, 999);
//                string result = cache.Get("index", key, k => Task.FromResult(k.ToString())).Result;
//            });

            foreach (int i in Enumerable.Range(0, 999))
            {
                string result = cache.Get("index", i, k => Task.FromResult(k.ToString())).Result;
            }

            //-----------------------------------------------------------------------------------------------------------
            // Assert
            //-----------------------------------------------------------------------------------------------------------
            cache.ActualCount.Should().BeGreaterThan(0);
        }
Esempio n. 4
0
        public void When_scenario_it_should_behavior()
        {
            //-----------------------------------------------------------------------------------------------------------
            // Arrange
            //-----------------------------------------------------------------------------------------------------------
            var cache = new FluidCache<string>(1000, TimeSpan.FromSeconds(10), TimeSpan.FromSeconds(10), () => DateTime.Now, null);
            cache.AddIndex("index", v => int.Parse(v));

            //-----------------------------------------------------------------------------------------------------------
            // Act
            //-----------------------------------------------------------------------------------------------------------
            //            Parallel.For(0, 100000, _ =>
            //            {
            //                int key = new Random().Next(0, 999);
            //                string result = cache.Get("index", key, k => Task.FromResult(k.ToString())).Result;
            //            });

            foreach (int i in Enumerable.Range(0, 999))
            {
                string result = cache.Get("index", i, k => Task.FromResult(k.ToString())).Result;
            }

            //-----------------------------------------------------------------------------------------------------------
            // Assert
            //-----------------------------------------------------------------------------------------------------------
            cache.ActualCount.Should().BeGreaterThan(0);
        }
Esempio n. 5
0
        public When_the_only_used_bag_expires()
        {
            var dateTime = DateTime.Now;

            Given(async() =>
            {
                cache     = new FluidCache <User>(1000, 5.Seconds(), 10.Seconds(), () => dateTime);
                indexById = cache.AddIndex("index", user => user.Id, id => Task.FromResult(new User {
                    Id = id
                }));

                await indexById.GetItem("key1", key => Task.FromResult(new User
                {
                    Id   = key,
                    Name = $"Name of {key}"
                }));
            });

            When(() =>
            {
                dateTime = dateTime.Add(1.Hours());

                func = () => indexById.GetItem("key2", key => Task.FromResult(new User
                {
                    Id   = key,
                    Name = $"Name of {key}"
                }));
            });
        }
Esempio n. 6
0
            public When_adding_the_same_new_item_concurrently()
            {
                Given(() =>
                {
                    cache     = new FluidCache <User>(1000, 5.Seconds(), 10.Seconds(), () => DateTime.Now);
                    indexById = cache.AddIndex("index", user => user.Id);
                });

                When(() =>
                {
                    Parallel.For(1, 1000, _ =>
                    {
                        try
                        {
                            cache.Add(new User
                            {
                                Id   = "item1",
                                Name = "Item1"
                            });
                        }
                        catch (InvalidOperationException)
                        {
                            // Expected, so ignore
                        }
                    });
                });
            }
Esempio n. 7
0
            public When_concurrently_adding_unique_items_directly_or_through_a_get()
            {
                Given(() =>
                {
                    cache     = new FluidCache <User>(1000, 5.Seconds(), 10.Seconds(), () => DateTime.Now);
                    indexById = cache.AddIndex("index", user => user.Id, id => Task.FromResult(new User {
                        Id = id
                    }));
                });

                When(() =>
                {
                    Parallel.For(0, 1000, iteration =>
                    {
                        if (iteration % 2 == 0)
                        {
                            cache.Add(new User
                            {
                                Id   = iteration.ToString(),
                                Name = iteration.ToString()
                            });
                        }
                        else
                        {
                            indexById.GetItem(iteration.ToString(), key => Task.FromResult(new User
                            {
                                Id   = key,
                                Name = key
                            }));
                        }
                    });
                });
            }
Esempio n. 8
0
        public SteamApi(Configuration config, HttpClient http)
        {
            var factory = new SteamWebInterfaceFactory(config.Steam?.WebApiKey ?? throw new ArgumentNullException(nameof(config.Steam.WebApiKey)));

            _user    = factory.CreateSteamWebInterface <SteamUser>(http);
            _stats   = factory.CreateSteamWebInterface <SteamUserStats>(http);
            _players = factory.CreateSteamWebInterface <PlayerService>(http);
            _store   = factory.CreateSteamStoreInterface(http);

            _steamStoreCache = new FluidCache <StoreAppDetailsDataModel>(
                1024,
                TimeSpan.FromSeconds(60),
                TimeSpan.FromDays(30),
                () => DateTime.UtcNow
                );
            _steamStoreCacheById = _steamStoreCache.AddIndex("byId", a => a.SteamAppId);

            _recentlyPlayedGames = new FluidCache <RecentlyPlayedGamesCacheItem>(
                128,
                TimeSpan.FromSeconds(60),
                TimeSpan.FromHours(1),
                () => DateTime.UtcNow
                );
            _recentlyPlayedGamesById = _recentlyPlayedGames.AddIndex("byId", a => a.Id);
        }
Esempio n. 9
0
        public WordVectorsService([NotNull] Configuration config, IHttpClient client)
        {
            _client = client;
            _config = config.WordVectors;

            _vectorCache = new FluidCache <WordVector>((int)_config.CacheSize, TimeSpan.FromSeconds(_config.CacheMinTimeSeconds), TimeSpan.FromMinutes(_config.CacheMaxTimeSeconds), () => DateTime.UtcNow);
            _indexByWord = _vectorCache.AddIndex("byWord", a => a.Word);
        }
Esempio n. 10
0
        public AlphaVantageForex(Configuration config, IHttpClientFactory http)
        {
            _key  = config.AlphaAdvantage?.Key ?? throw new ArgumentNullException(nameof(config.AlphaAdvantage.Key));
            _http = http.CreateClient();

            _cache        = new FluidCache <IForexQuote>(config.AlphaAdvantage.CacheSize, TimeSpan.FromSeconds(config.AlphaAdvantage.CacheMinAgeSeconds), TimeSpan.FromSeconds(config.AlphaAdvantage.CacheMaxAgeSeconds), () => DateTime.UtcNow);
            _bySymbolPair = _cache.AddIndex("BySymbolPair", a => new KeyValuePair <string, string>(a.FromCode, a.ToCode));
        }
Esempio n. 11
0
        public AlphaVantageForex([NotNull] Configuration config, IHttpClient http)
        {
            _config = config.AlphaAdvantage;
            _http   = http;

            _cache        = new FluidCache <IForexQuote>(_config.CacheSize, TimeSpan.FromSeconds(_config.CacheMinAgeSeconds), TimeSpan.FromSeconds(_config.CacheMaxAgeSeconds), () => DateTime.UtcNow);
            _bySymbolPair = _cache.AddIndex("BySymbolPair", a => new KeyValuePair <string, string>(a.FromCode, a.ToCode));
        }
Esempio n. 12
0
        public AlphaVantageStocks([NotNull] Configuration config, IHttpClient http)
        {
            _config = config.AlphaAdvantage;
            _http   = http;

            _cache    = new FluidCache <IStockQuote>(_config.CacheSize, TimeSpan.FromSeconds(_config.CacheMinAgeSeconds), TimeSpan.FromSeconds(_config.CacheMaxAgeSeconds), () => DateTime.UtcNow);
            _bySymbol = _cache.AddIndex("BySymbol", a => a.Symbol);
        }
Esempio n. 13
0
 public UrbanDictionaryApi([NotNull] Configuration config, [NotNull] IHttpClient http)
 {
     _http            = http;
     _definitionCache = new FluidCache <CacheEntry>(
         (int)config.UrbanDictionary.CacheSize,
         TimeSpan.FromSeconds(config.UrbanDictionary.CacheMinTimeSeconds),
         TimeSpan.FromSeconds(config.UrbanDictionary.CacheMaxTimeSeconds),
         () => DateTime.UtcNow
         );
     _definitionsByWord = _definitionCache.AddIndex("byWord", a => a.Word);
 }
Esempio n. 14
0
 public UrbanDictionaryApi(Configuration config, IHttpClientFactory http)
 {
     _http            = http.CreateClient();
     _definitionCache = new FluidCache <CacheEntry>(
         (int)(config.UrbanDictionary?.CacheSize ?? 128),
         TimeSpan.FromSeconds(config.UrbanDictionary?.CacheMinTimeSeconds ?? 30),
         TimeSpan.FromSeconds(config.UrbanDictionary?.CacheMaxTimeSeconds ?? 3600),
         () => DateTime.UtcNow
         );
     _definitionsByWord = _definitionCache.AddIndex("byWord", a => a.Word);
 }
Esempio n. 15
0
        public AlphaVantageStocks(Configuration config, IHttpClientFactory http)
        {
            if (config.AlphaAdvantage == null)
            {
                throw new ArgumentNullException(nameof(config.AlphaAdvantage));
            }

            _key      = config.AlphaAdvantage.Key ?? throw new ArgumentNullException(nameof(config.AlphaAdvantage));
            _http     = http.CreateClient();
            _cache    = new FluidCache <IStockQuote>(config.AlphaAdvantage.CacheSize, TimeSpan.FromSeconds(config.AlphaAdvantage.CacheMinAgeSeconds), TimeSpan.FromSeconds(config.AlphaAdvantage.CacheMaxAgeSeconds), () => DateTime.UtcNow);
            _bySymbol = _cache.AddIndex("BySymbol", a => a.Symbol);
        }
Esempio n. 16
0
            public When_an_item_did_not_exist_in_the_cache()
            {
                Given(() =>
                {
                    cache     = new FluidCache <User>(1000, 5.Seconds(), 10.Seconds(), () => DateTime.Now);
                    indexById = cache.AddIndex("index", user => user.Id, id => Task.FromResult(new User {
                        Id = id
                    }));
                });

                When(async() => { await indexById.GetItem("itemkey"); });
            }
Esempio n. 17
0
        public ProCoinMarketCapCrypto([NotNull] Configuration config, [NotNull] IHttpClient http)
        {
            _http = http;
            _key  = config.CoinMarketCap.Key;

            _currencyCache    = new FluidCache <ICurrency>(config.CoinMarketCap.CacheSize, TimeSpan.FromSeconds(config.CoinMarketCap.CacheMinAgeSeconds), TimeSpan.FromSeconds(config.CoinMarketCap.CacheMaxAgeSeconds), () => DateTime.UtcNow);
            _currencyById     = _currencyCache.AddIndex("IndexByUniqueId", a => a.Id);
            _currencyByName   = _currencyCache.AddIndex("IndexByName", a => a.Name);
            _currencyBySymbol = _currencyCache.AddIndex("IndexBySymbol", a => a.Symbol);

            _tickerCache    = new FluidCache <ITicker>(config.CoinMarketCap.CacheSize, TimeSpan.FromSeconds(config.CoinMarketCap.CacheMinAgeSeconds), TimeSpan.FromSeconds(config.CoinMarketCap.CacheMaxAgeSeconds), () => DateTime.UtcNow);
            _tickerById     = _tickerCache.AddIndex("IndexById", a => a.Currency.Id);
            _tickerBySymbol = _tickerCache.AddIndex("IndexBySymbol", a => a.Currency.Symbol);
        }
Esempio n. 18
0
            public When_an_item_does_not_exist_in_the_cache_and_the_factory_returns_a_null_task()
            {
                Given(() =>
                {
                    cache     = new FluidCache <User>(1000, 5.Seconds(), 10.Seconds(), () => DateTime.Now);
                    indexById = cache.AddIndex("index", user => user.Id, id => Task.FromResult(new User {
                        Id = id
                    }));
                });

                When(() =>
                {
                    return(async() => await indexById.GetItem("itemkey", k => null));
                });
            }
Esempio n. 19
0
            public When_a_case_insensitive_comparer_is_used_for_an_index_and_getting_an_item_by_the_key_with_a_different_case()
            {
                Given(() =>
                {
                    cache     = new FluidCache <User>(1000, 5.Seconds(), 10.Seconds(), () => DateTime.Now);
                    indexById = cache.AddIndex("index", user => user.Id, keyEqualityComparer: StringComparer.OrdinalIgnoreCase);

                    UseThe(new User {
                        Id = "TheId"
                    });
                    cache.Add(The <User>());
                });

                When(() => indexById.GetItem("theID"));
            }
Esempio n. 20
0
        private async Task <TItem> GetOrDownload <TKey, TItem, TResponse>(TKey key, FluidCache <TItem> cache, IIndex <TKey, TItem> index, Func <TKey, Task <HttpResponseMessage> > download, Func <TResponse, IEnumerable <TItem> > extract)
            where TItem : class
        {
            //Get it from the cache if possible
            var item = await index.GetItem(key);

            if (item != null)
            {
                return(item);
            }

            //No luck, download the details from the API
            var result = await download(key);

            if (!result.IsSuccessStatusCode)
            {
                return(null);
            }

            //Deserialize response
            TResponse model;
            var       serializer = new JsonSerializer();

            using (var sr = new StreamReader(await result.Content.ReadAsStreamAsync()))
                using (var jsonTextReader = new JsonTextReader(sr))
                    model = serializer.Deserialize <TResponse>(jsonTextReader);

            if (model == null)
            {
                return(null);
            }

            var extracted = extract(model);

            if (extracted == null)
            {
                return(null);
            }

            //That could get several currencies, add them all to cache
            foreach (var extractedItem in extracted)
            {
                cache.Add(extractedItem);
            }

            //Get the item from cache again, hopefully with more success this time
            return(await index.GetItem(key));
        }
Esempio n. 21
0
            public When_capacity_is_at_max_but_an_objects_minimal_age_has_not_been_reached()
            {
                Given(() =>
                {
                    now = 25.December(2015).At(10, 22);

                    int capacity = 1;

                    cache = new FluidCache <string>(capacity, TimeSpan.FromMinutes(5), TimeSpan.FromHours(1), () => now, null);
                    index = cache.AddIndex("strings", s => s, key => Task.FromResult(key));
                });

                When(async() =>
                {
                    await index.GetItem("item1");
                    return(await index.GetItem("item2"));
                });
            }
Esempio n. 22
0
            public When_requesting_a_large_number_of_items_from_the_cache()
            {
                Given(() =>
                {
                    cache     = new FluidCache <User>(1000, 5.Seconds(), 10.Seconds(), () => DateTime.Now, null);
                    indexById = cache.AddIndex("index", user => user.Id);
                });

                When(async() =>
                {
                    foreach (int key in Enumerable.Range(0, 1000))
                    {
                        await Task.Delay(10);
                        await indexById.GetItem(key, id => Task.FromResult(new User {
                            Id = id
                        }));
                    }
                });
            }
Esempio n. 23
0
            public When_requesting_the_same_new_item_concurrently()
            {
                Given(() =>
                {
                    cache     = new FluidCache <User>(1000, 5.Seconds(), 10.Seconds(), () => DateTime.Now);
                    indexById = cache.AddIndex("index", user => user.Id);
                });

                When(() =>
                {
                    Parallel.For(1, 100000, _ =>
                    {
                        indexById.GetItem("Item1", id => Task.FromResult(new User
                        {
                            Id   = id,
                            Name = "Item1"
                        })).Wait();
                    });
                });
            }
Esempio n. 24
0
            public When_capacity_is_at_max_and_an_objects_minimal_age_has_been_reached()
            {
                Given(() =>
                {
                    now = 25.December(2015).At(10, 22);

                    capacity = 100;

                    cache = new FluidCache <User>(capacity, minimumAge, 1.Hours(), () => now);

                    index = cache.AddIndex("UsersById", u => u.Id, key => Task.FromResult(new User
                    {
                        Id   = key,
                        Name = "key"
                    }));
                });

                When(async() =>
                {
                    theOriginalUser = await index.GetItem("the user");

                    for (int id = 0; id < capacity; id++)
                    {
                        await index.GetItem("user " + id);
                    }

                    now = now.Add(minimumAge + 2.Minutes());

                    // Trigger evaluating of the cache
                    await index.GetItem("some user to trigger a cleanup");

                    // Make sure any weak references are cleaned up
                    GC.Collect();

                    // Try to get the same user again.
                    return(await index.GetItem("the user"));
                });
            }
Esempio n. 25
0
        static void Main(string[] args)
        {
            var cache = new FluidCache <User>(50000, TimeSpan.FromSeconds(30), TimeSpan.FromMinutes(2), () => DateTime.UtcNow);
            var index = cache.AddIndex("users", u => u.Id);

            Parallel.For(0, long.MaxValue, i =>
            {
                index.GetItem(i.ToString(), id => Task.FromResult(new User
                {
                    Id   = id,
                    Name = id
                })).Wait();

                if (i % 10000 == 0)
                {
                    Console.WriteLine($"Requested {i} items from the cache");
                    Console.WriteLine(cache.Statistics);
                }
            });

            Console.WriteLine("Done");
            Console.ReadLine();
        }
 protected BaseMikibotSearchService()
 {
     _cache    = new FluidCache <TItem>(1024, TimeSpan.FromHours(1), TimeSpan.FromDays(7), () => DateTime.UtcNow);
     _itemById = _cache.AddIndex("id", ExtractId);
 }