cache2k и Generic T не играют хорошо вместе - PullRequest
0 голосов
/ 27 сентября 2018

В руководстве пользователя cache2k, §2.3.Cache Aside содержит пример кода и предложение об кэшировании.

Cache<String, String> routeToAirline = new Cache2kBuilder<String, String>() {}
  .name("routeToAirline")
  .build();

private String findFavoriteAirline(String origin, String destination) {
  // expensive operation to find the best airline for this route
  // for example, ask all friends...
}

public String lookupFavoirteAirline(String origin, String destination) {
  String route = origin + "-" + destination;
  String airline = routeToAirline.peek(route);
  if (airline == null) {
    airline = findFavoriteAirline(origin, destination);
    routeToAirline.put(route, airline);
  }
  return airline;
}

Приведенный выше шаблон называется кэшированием.

И я как"Отлично .... Я люблю шаблон Cache Aside".Поэтому я пытаюсь реализовать один, используя дженерики вместо жесткого кодирования типа (значения).

Я придумал это, используя дженерики.И я внедряю метод, который «получает» товар (Поставщик).Код многократного использования!

package mypackage;

import java.util.function.Supplier;

import org.cache2k.Cache;
import org.cache2k.Cache2kBuilder;

//import mypackage.interfaces.IGenericCacheAside;

public class Cache2kGenericCacheAside<TEntity> ////implements IGenericCacheAside<TEntity> {

    public final String CacheKeyPrefix = "GenericCacheAsidePrefix";

    private volatile Cache<String, TEntity> theCache = null; /* static not allowed for TEntity */

    public TEntity GetCacheAsideItem(String uniqueIdentifier, long itemLifeMiliseconds,
            final Supplier<TEntity> valueFactory) {
        this.initiateCacheObject();
        String cacheKey = this.GetFullCacheKey(uniqueIdentifier);
        TEntity cachedOrFreshItem = this.GetFromCache(cacheKey, itemLifeMiliseconds, valueFactory);
        return cachedOrFreshItem;
    }

    public TEntity RemoveCacheAsideItem(String uniqueIdentifier) {
        TEntity removedItem = null;
        String cacheKey = this.GetFullCacheKey(uniqueIdentifier);
        if (this.theCache.containsKey(uniqueIdentifier)) {
            removedItem = this.theCache.peekAndRemove(cacheKey);
        }
        return removedItem;
    }

    private void initiateCacheObject(/* long duration, TimeUnit tu, long capacity */) {
        if (null == this.theCache) {

            theCache = new Cache2kBuilder<String, TEntity>() {
            }.name("myCache").eternal(true).build();

        }
    }



    private TEntity GetFromCache(String cacheKey, long millis, final Supplier<TEntity> valueFactory) {
        TEntity cachedOrFreshItem = theCache.peek(cacheKey);
        if (cachedOrFreshItem == null) {
            cachedOrFreshItem = valueFactory.get();
            theCache.put(cacheKey, cachedOrFreshItem);
            theCache.expireAt(cacheKey, millis);
        }

        return cachedOrFreshItem;
    }

    private String GetFullCacheKey(String uniqueIdentifier) {
        String returnValue = CacheKeyPrefix + uniqueIdentifier;
        return returnValue;
    }
}

Я получаю ошибку времени выполнения:

java.lang.IllegalArgumentException: тип времени выполнения недоступен, получено: TEntity

Думаю, я попал в этот неизвестный ранее мир типа стирания .

Есть ли способ реализовать этот код Generic-CacheAside?Этот скрытый драгоценный камень (стирание) ужасен.

<dependency>
    <groupId>org.cache2k</groupId>
    <artifactId>cache2k-api</artifactId>
    <version>1.2.0.Final</version>
</dependency>

APPEND:

Вот пример.По сути, в любое время мне нужно кэшировать «что-то», которое не управляется параметром для поиска.В моем примере ниже я кеширую SystemSetting (s).Нет параметров для управления поиском.

private static int NewedUpCounter = 0;
private static int CurrentRunCacheReads = 0;

private static void RunCacheAsideStuff() {

    /* example ONLY. use construction-injection for "real" code */
    ////IGenericCacheAside<Collection<SystemSetting>> igca = new Cache2kGenericCacheAside<Collection<SystemSetting>>();
    /* or */
    Cache2kGenericCacheAside<Collection<SystemSetting>> igca = new Cache2kGenericCacheAside<Collection<SystemSetting>>();

    for (int i = 0; i < 20; i++) {

        /* in the below, it shows how the "time to keep in the cache" might change over time */
        int cacheMilliseconds = 2500 + (500 * i);
        System.out.println(String.format("        cacheMilliseconds=%1s",
                cacheMilliseconds));            
        Collection<SystemSetting> cacheAsideSettings = igca.GetCacheAsideItem("myuniqueIdentifier", cacheMilliseconds,
                TimeUnit.MILLISECONDS, App::CreateDummySystemSettings);

        if (null != cacheAsideSettings) {
            System.out.println("--------------");
            System.out.println(String.format("        CurrentRunCacheReads=%1s",
                    ++CurrentRunCacheReads));                   
            System.out.println(String.format("        Cached Collection<SystemSetting> Read .. size=%1s",
                    cacheAsideSettings.size()));
            for (SystemSetting sett : cacheAsideSettings) {
                System.out.println(String.format(
                        "cacheAsideSettings !! SystemSetting.Key=%1s, SystemSetting.Value = %2s, i = %3s , Time= %4s",
                        sett.getSystemSettingKey(), sett.getSettingValue(), i, LocalDateTime.now()));
            }
            System.out.println("--------------");
        }

        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
    }

    System.out.println(String.format("NewedUpCounter=%1s",
            NewedUpCounter));

}

private static Collection<SystemSetting> CreateDummySystemSettings() {

    NewedUpCounter++;
    CurrentRunCacheReads=0;

    long LOWER_RANGE = 10000; // assign lower range value
    long UPPER_RANGE = 20000; // assign upper range value
    Random random = new Random();

    long randomValue = LOWER_RANGE + (long) (random.nextDouble() * (UPPER_RANGE - LOWER_RANGE));

    Collection<SystemSetting> returnItems = new ArrayList<>();
    for (int i = 101; i < 104; i++) {
        SystemSetting newSetting = new SystemSetting();
        newSetting.setSystemSettingKey(i);
        newSetting.setSettingValue(String.format("ValueOf%1s*", randomValue));
        returnItems.add(newSetting);
    }

    System.out.println(String.format("NEW Collection<SystemSetting> CREATED !! size=%1s  ************************************************", returnItems.size()));

    return returnItems;
}

И вывод.Пример, показывающий, что элемент / время в кэше может измениться.

        cacheMilliseconds=2500
NEW Collection<SystemSetting> CREATED !! size=3  ************************************************
--------------
        CurrentRunCacheReads=1
        Cached Collection<SystemSetting> Read .. size=3
cacheAsideSettings !! SystemSetting.Key=101, SystemSetting.Value = ValueOf14000*, i =   0 , Time= 2018-09-28T13:04:14.043
cacheAsideSettings !! SystemSetting.Key=102, SystemSetting.Value = ValueOf14000*, i =   0 , Time= 2018-09-28T13:04:14.052
cacheAsideSettings !! SystemSetting.Key=103, SystemSetting.Value = ValueOf14000*, i =   0 , Time= 2018-09-28T13:04:14.052
--------------
        cacheMilliseconds=3000
--------------
        CurrentRunCacheReads=2
        Cached Collection<SystemSetting> Read .. size=3
cacheAsideSettings !! SystemSetting.Key=101, SystemSetting.Value = ValueOf14000*, i =   1 , Time= 2018-09-28T13:04:15.052
cacheAsideSettings !! SystemSetting.Key=102, SystemSetting.Value = ValueOf14000*, i =   1 , Time= 2018-09-28T13:04:15.053
cacheAsideSettings !! SystemSetting.Key=103, SystemSetting.Value = ValueOf14000*, i =   1 , Time= 2018-09-28T13:04:15.053
--------------
        cacheMilliseconds=3500
--------------
        CurrentRunCacheReads=3
        Cached Collection<SystemSetting> Read .. size=3
cacheAsideSettings !! SystemSetting.Key=101, SystemSetting.Value = ValueOf14000*, i =   2 , Time= 2018-09-28T13:04:16.054
cacheAsideSettings !! SystemSetting.Key=102, SystemSetting.Value = ValueOf14000*, i =   2 , Time= 2018-09-28T13:04:16.054
cacheAsideSettings !! SystemSetting.Key=103, SystemSetting.Value = ValueOf14000*, i =   2 , Time= 2018-09-28T13:04:16.054
--------------
        cacheMilliseconds=4000
NEW Collection<SystemSetting> CREATED !! size=3  ************************************************
--------------
        CurrentRunCacheReads=1
        Cached Collection<SystemSetting> Read .. size=3
cacheAsideSettings !! SystemSetting.Key=101, SystemSetting.Value = ValueOf17155*, i =   3 , Time= 2018-09-28T13:04:17.055
cacheAsideSettings !! SystemSetting.Key=102, SystemSetting.Value = ValueOf17155*, i =   3 , Time= 2018-09-28T13:04:17.055
cacheAsideSettings !! SystemSetting.Key=103, SystemSetting.Value = ValueOf17155*, i =   3 , Time= 2018-09-28T13:04:17.055
--------------
        cacheMilliseconds=4500
--------------
        CurrentRunCacheReads=2
        Cached Collection<SystemSetting> Read .. size=3
cacheAsideSettings !! SystemSetting.Key=101, SystemSetting.Value = ValueOf17155*, i =   4 , Time= 2018-09-28T13:04:18.056
cacheAsideSettings !! SystemSetting.Key=102, SystemSetting.Value = ValueOf17155*, i =   4 , Time= 2018-09-28T13:04:18.056
cacheAsideSettings !! SystemSetting.Key=103, SystemSetting.Value = ValueOf17155*, i =   4 , Time= 2018-09-28T13:04:18.056
--------------
        cacheMilliseconds=5000
--------------
        CurrentRunCacheReads=3
        Cached Collection<SystemSetting> Read .. size=3
cacheAsideSettings !! SystemSetting.Key=101, SystemSetting.Value = ValueOf17155*, i =   5 , Time= 2018-09-28T13:04:19.057
cacheAsideSettings !! SystemSetting.Key=102, SystemSetting.Value = ValueOf17155*, i =   5 , Time= 2018-09-28T13:04:19.058
cacheAsideSettings !! SystemSetting.Key=103, SystemSetting.Value = ValueOf17155*, i =   5 , Time= 2018-09-28T13:04:19.058
--------------
        cacheMilliseconds=5500
--------------
        CurrentRunCacheReads=4
        Cached Collection<SystemSetting> Read .. size=3
cacheAsideSettings !! SystemSetting.Key=101, SystemSetting.Value = ValueOf17155*, i =   6 , Time= 2018-09-28T13:04:20.058
cacheAsideSettings !! SystemSetting.Key=102, SystemSetting.Value = ValueOf17155*, i =   6 , Time= 2018-09-28T13:04:20.058
cacheAsideSettings !! SystemSetting.Key=103, SystemSetting.Value = ValueOf17155*, i =   6 , Time= 2018-09-28T13:04:20.058
--------------
        cacheMilliseconds=6000
NEW Collection<SystemSetting> CREATED !! size=3  ************************************************
--------------
        CurrentRunCacheReads=1
        Cached Collection<SystemSetting> Read .. size=3
cacheAsideSettings !! SystemSetting.Key=101, SystemSetting.Value = ValueOf17444*, i =   7 , Time= 2018-09-28T13:04:21.059
cacheAsideSettings !! SystemSetting.Key=102, SystemSetting.Value = ValueOf17444*, i =   7 , Time= 2018-09-28T13:04:21.060
cacheAsideSettings !! SystemSetting.Key=103, SystemSetting.Value = ValueOf17444*, i =   7 , Time= 2018-09-28T13:04:21.060
--------------
        cacheMilliseconds=6500
--------------
        CurrentRunCacheReads=2
        Cached Collection<SystemSetting> Read .. size=3
cacheAsideSettings !! SystemSetting.Key=101, SystemSetting.Value = ValueOf17444*, i =   8 , Time= 2018-09-28T13:04:22.060
cacheAsideSettings !! SystemSetting.Key=102, SystemSetting.Value = ValueOf17444*, i =   8 , Time= 2018-09-28T13:04:22.060
cacheAsideSettings !! SystemSetting.Key=103, SystemSetting.Value = ValueOf17444*, i =   8 , Time= 2018-09-28T13:04:22.060
--------------
        cacheMilliseconds=7000
--------------
        CurrentRunCacheReads=3
        Cached Collection<SystemSetting> Read .. size=3
cacheAsideSettings !! SystemSetting.Key=101, SystemSetting.Value = ValueOf17444*, i =   9 , Time= 2018-09-28T13:04:23.060
cacheAsideSettings !! SystemSetting.Key=102, SystemSetting.Value = ValueOf17444*, i =   9 , Time= 2018-09-28T13:04:23.060
cacheAsideSettings !! SystemSetting.Key=103, SystemSetting.Value = ValueOf17444*, i =   9 , Time= 2018-09-28T13:04:23.060
--------------
        cacheMilliseconds=7500
--------------
        CurrentRunCacheReads=4
        Cached Collection<SystemSetting> Read .. size=3
cacheAsideSettings !! SystemSetting.Key=101, SystemSetting.Value = ValueOf17444*, i =  10 , Time= 2018-09-28T13:04:24.060
cacheAsideSettings !! SystemSetting.Key=102, SystemSetting.Value = ValueOf17444*, i =  10 , Time= 2018-09-28T13:04:24.061
cacheAsideSettings !! SystemSetting.Key=103, SystemSetting.Value = ValueOf17444*, i =  10 , Time= 2018-09-28T13:04:24.061
--------------
        cacheMilliseconds=8000
--------------
        CurrentRunCacheReads=5
        Cached Collection<SystemSetting> Read .. size=3
cacheAsideSettings !! SystemSetting.Key=101, SystemSetting.Value = ValueOf17444*, i =  11 , Time= 2018-09-28T13:04:25.061
cacheAsideSettings !! SystemSetting.Key=102, SystemSetting.Value = ValueOf17444*, i =  11 , Time= 2018-09-28T13:04:25.061
cacheAsideSettings !! SystemSetting.Key=103, SystemSetting.Value = ValueOf17444*, i =  11 , Time= 2018-09-28T13:04:25.061
--------------
        cacheMilliseconds=8500
--------------
        CurrentRunCacheReads=6
        Cached Collection<SystemSetting> Read .. size=3
cacheAsideSettings !! SystemSetting.Key=101, SystemSetting.Value = ValueOf17444*, i =  12 , Time= 2018-09-28T13:04:26.063
cacheAsideSettings !! SystemSetting.Key=102, SystemSetting.Value = ValueOf17444*, i =  12 , Time= 2018-09-28T13:04:26.063
cacheAsideSettings !! SystemSetting.Key=103, SystemSetting.Value = ValueOf17444*, i =  12 , Time= 2018-09-28T13:04:26.064
--------------
        cacheMilliseconds=9000
NEW Collection<SystemSetting> CREATED !! size=3  ************************************************
--------------
        CurrentRunCacheReads=1
        Cached Collection<SystemSetting> Read .. size=3
cacheAsideSettings !! SystemSetting.Key=101, SystemSetting.Value = ValueOf14680*, i =  13 , Time= 2018-09-28T13:04:27.065
cacheAsideSettings !! SystemSetting.Key=102, SystemSetting.Value = ValueOf14680*, i =  13 , Time= 2018-09-28T13:04:27.065
cacheAsideSettings !! SystemSetting.Key=103, SystemSetting.Value = ValueOf14680*, i =  13 , Time= 2018-09-28T13:04:27.066
--------------
        cacheMilliseconds=9500
--------------
        CurrentRunCacheReads=2
        Cached Collection<SystemSetting> Read .. size=3
cacheAsideSettings !! SystemSetting.Key=101, SystemSetting.Value = ValueOf14680*, i =  14 , Time= 2018-09-28T13:04:28.066
cacheAsideSettings !! SystemSetting.Key=102, SystemSetting.Value = ValueOf14680*, i =  14 , Time= 2018-09-28T13:04:28.066
cacheAsideSettings !! SystemSetting.Key=103, SystemSetting.Value = ValueOf14680*, i =  14 , Time= 2018-09-28T13:04:28.066
--------------
        cacheMilliseconds=10000
--------------
        CurrentRunCacheReads=3
        Cached Collection<SystemSetting> Read .. size=3
cacheAsideSettings !! SystemSetting.Key=101, SystemSetting.Value = ValueOf14680*, i =  15 , Time= 2018-09-28T13:04:29.067
cacheAsideSettings !! SystemSetting.Key=102, SystemSetting.Value = ValueOf14680*, i =  15 , Time= 2018-09-28T13:04:29.067
cacheAsideSettings !! SystemSetting.Key=103, SystemSetting.Value = ValueOf14680*, i =  15 , Time= 2018-09-28T13:04:29.067
--------------
        cacheMilliseconds=10500
--------------
        CurrentRunCacheReads=4
        Cached Collection<SystemSetting> Read .. size=3
cacheAsideSettings !! SystemSetting.Key=101, SystemSetting.Value = ValueOf14680*, i =  16 , Time= 2018-09-28T13:04:30.068
cacheAsideSettings !! SystemSetting.Key=102, SystemSetting.Value = ValueOf14680*, i =  16 , Time= 2018-09-28T13:04:30.068
cacheAsideSettings !! SystemSetting.Key=103, SystemSetting.Value = ValueOf14680*, i =  16 , Time= 2018-09-28T13:04:30.068
--------------
        cacheMilliseconds=11000
--------------
        CurrentRunCacheReads=5
        Cached Collection<SystemSetting> Read .. size=3
cacheAsideSettings !! SystemSetting.Key=101, SystemSetting.Value = ValueOf14680*, i =  17 , Time= 2018-09-28T13:04:31.068
cacheAsideSettings !! SystemSetting.Key=102, SystemSetting.Value = ValueOf14680*, i =  17 , Time= 2018-09-28T13:04:31.068
cacheAsideSettings !! SystemSetting.Key=103, SystemSetting.Value = ValueOf14680*, i =  17 , Time= 2018-09-28T13:04:31.068
--------------
        cacheMilliseconds=11500
--------------
        CurrentRunCacheReads=6
        Cached Collection<SystemSetting> Read .. size=3
cacheAsideSettings !! SystemSetting.Key=101, SystemSetting.Value = ValueOf14680*, i =  18 , Time= 2018-09-28T13:04:32.068
cacheAsideSettings !! SystemSetting.Key=102, SystemSetting.Value = ValueOf14680*, i =  18 , Time= 2018-09-28T13:04:32.068
cacheAsideSettings !! SystemSetting.Key=103, SystemSetting.Value = ValueOf14680*, i =  18 , Time= 2018-09-28T13:04:32.068
--------------
        cacheMilliseconds=12000
--------------
        CurrentRunCacheReads=7
        Cached Collection<SystemSetting> Read .. size=3
cacheAsideSettings !! SystemSetting.Key=101, SystemSetting.Value = ValueOf14680*, i =  19 , Time= 2018-09-28T13:04:33.069
cacheAsideSettings !! SystemSetting.Key=102, SystemSetting.Value = ValueOf14680*, i =  19 , Time= 2018-09-28T13:04:33.069
cacheAsideSettings !! SystemSetting.Key=103, SystemSetting.Value = ValueOf14680*, i =  19 , Time= 2018-09-28T13:04:33.069
--------------
NewedUpCounter=4 /* this last one not accurate since its "bailing out */

1 Ответ

0 голосов
/ 27 октября 2018

Выражение создания анонимного класса new Cache2kBuilder<String, String>() {} используется в качестве «токена супертипа» для представления параметризованного типа во время выполнения.Для этого они создают подкласс (обычно анонимный класс), который расширяет параметризованный тип, где аргументы типа - это конкретные типы, фиксированные (жестко запрограммированные) во время компиляции.Поскольку суперкласс класса является частью объявления класса, он хранится с общей информацией в части объявления файла класса, и эта информация может быть получена во время выполнения с помощью отражения.

Обратите внимание, что можетбыть извлеченным из файла класса во время выполнения - это именно то, что было жестко запрограммировано во время компиляции.Вот почему new Cache2kBuilder<String, TEntity>() {} не работает - то, что было жестко запрограммировано в исходном коде во время компиляции, - это то, что вместо конкретного класса есть переменная типа TEntity.

Cache2kпредоставляет другой способ построения Cache2kBuilder, если класс не может быть исправлен во время компиляции, и будет известен только во время выполнения:

theCache = Cache2kBuilder.of(String.class, entityClass)
  .name("myCache").eternal(true).build();

, где entityClass - это Class<TEntity>, который являетсяКласс объекта класса сущности во время выполнения.Таким образом, вы должны будете также передать объект Class для объекта, а не просто Supplier для него.

...