Кеш ключевая организационная проблема - PullRequest
1 голос
/ 28 января 2011

У моей сущности есть два уникальных идентификатора (да, это неправильно, но это требование).Я хочу организовать кеш таких экземпляров.Поиск в кеше может быть выполнен по id1 ИЛИ id2 ИЛИ id1 и id2.Поиск по id1 и id2 в порядке - я сделаю составной ключ.Но как бороться с просто поиском по одному из идентификаторов.Каким должен быть ключ кеша?Я использую ehcache.

У меня есть ситуация, когда несколько ключей могут ссылаться на один и тот же объект.

Как ehcache не поддерживает эту функцию, один и тот же объект будет сохранен для каждого ключа (nэкземпляры одного и того же объекта, где n - это число различных ключей, из которых можно ссылаться на этот объект).

В какой-то момент у меня есть знания для вычисления других ключей, но не раньше, чем они мне понадобятся.

Ситуация:

GEN KEY (1) Проверить, находится ли объект в кэше (2) ИСТИНА: извлечь его

ЛОЖЬ: обработать новый объект (3) Поместить его в ehcacheвозвращаем ОБЪЕКТ

В точке (1) просто знаю один из ключей.В точке (3) есть возможность узнать все ключи, которые объект может связать с ним в ehcache.Проблема в том, что ключи нужны в точке (2).

Thx

Ответы [ 3 ]

1 голос
/ 28 января 2011

Одним из вариантов будет использование двух карт.Один для каждого набора идентификаторов, но оба указывают на один и тот же набор значений.

Если поиск выполняется по id1, просто найдите значение на первой карте, если на id2, просто посмотрите на второй карте.Если вам нужно выполнить поиск по обоим, найдите оба значения и посмотрите, идентичны ли они.

Обновлен на основе обновлений вашего вопроса и комментариев ниже: Используйте оба ключа в своей электронной почте.Да, это займет больше места, и могут быть случаи, когда искомый объект уже находится в кеше под другим ключом.Однако в кеше должны храниться общие проверенные ключи.Не должно заботиться о том, что значение может существовать под другим ключом.Поэтому я бы не стал пытаться оптимизировать ваш кэш для поиска по двум ключам.

1 голос
/ 22 августа 2011

Чтобы выполнить то, что вы хотите, вы можете сделать это путем транзитивности, храня не только объект в кэше, но и индекс, который указывает на ваш объект, используя каждый из ключей.например:кэш [ "key1"] = theIndex;кэш [ "key2"] = theIndex;cache [theIndex] = object;

Итак, когда вы запрашиваете кеш ["key1"], вы получите индекс (вы должны знать, что это индекс), а затем получите реальный объект, используя этот индекс.

Код может выглядеть примерно так:

 public class CacheUtil {

   ... any necessary code here

   public static void put(String key, Serializable obj) {
    if (obj instance of Cacheable) { 
      //Cacheable interface identifies the cacheable object that has the getKeys method
      String[] keys = obj.getKeys();
      if (keys != null && keys.length > 0) {

        for (String myKey : keys) {
          //CacheIndex identifies the index
          cache.put(new Element(myKey, new CacheIndex(hashCode))); 
        }
        key = hashCode(keys); //change the key. Can be a hashcode of the keys
      }
    }

    cache.put(new Element(key, obj));
  }

  public static Serializable get(String key) {

    Serializable obj = cache.get(key);

    return ((null != serializable) && (serializable instanceof CacheIndex)) ?
            get(((CacheIndex)serializable).getIndex(), area) : obj;
  }

}
1 голос
/ 28 января 2011

Я не могу сказать для ehcache, но у меня была похожая проблема для HashMap, используемого в качестве кэша.Я просто помещаю каждое значение дважды на карту, это не так дорого и хорошо работает.

Из-за того, что мои ключи были разных типов, я использовал Map<Object, V>.

...