/** * get data synchronous and preload new data asynchronous according to keyList * * @param key * @param keyList key list, if is null, not preload, else preload forward by {@link * #preloadDataForward(Object, List, int)}, preload backward by {@link * #preloadDataBackward(Object, List, int)} * @return element if this cache contains the specified key, else get data realtime and wait for * it * @see PreloadDataCache#get(Object) */ public CacheObject<V> get(K key, List<K> keyList) { if (key == null) { return null; } // if list is not null, preload data if (!ListUtils.isEmpty(keyList)) { preloadDataForward(key, keyList, forwardCacheNumber); preloadDataBackward(key, keyList, backwardCacheNumber); } return get(key); }
/** * preload data backward * * <ul> * <strong>Preload rule below:</strong><br> * If key is null or list is empty, not preload, else circle keyList back to front.<br> * If entry in the list equals to key, begin preload until to the front of list or preload count * has reached cacheCount, like this: * <li>if entry is already in cache or is getting data, continue last entry. else * <li>new thread to get data and continue last entry * </ul> * * @param key * @param keyList if is null, not preload * @param cacheCount count for preload forward * @return count for getting data, that is cacheCount minus count of keys whose alreadey in cache */ protected int preloadDataBackward(K key, List<K> keyList, int cacheCount) { int gettingDataCount = 0; if (key != null && !ListUtils.isEmpty(keyList) && onGetDataListener != null) { int cachedCount = 0; boolean beginCount = false; for (int i = keyList.size() - 1; i >= 0 && cachedCount <= cacheCount; i--) { K k = keyList.get(i); if (ObjectUtils.isEquals(k, key)) { beginCount = true; continue; } if (k != null && beginCount) { cachedCount++; if (gettingData(k) != null) { gettingDataCount++; } } } } return gettingDataCount; }