private void assertFurtherValuesSorting(final FDate key) { final FDate firstKey = extractKey(key, furtherValues.getHead()); if (firstKey.compareTo(key) <= -1) { /* * readAllValuesAscendingFrom loads all data, thus we set the min key very deep so that later queries are * skipped if they are before minKey */ minKey = minKey(); } if (minKeyInDB == null || firstKey.compareTo(minKey) <= -1) { minKeyInDB = firstKey; } minKeyInDBFromLoadFurtherValues = FDates.min(minKeyInDBFromLoadFurtherValues, firstKey); final FDate lastKey = extractKey(key, furtherValues.getTail()); if (maxKeyInDB == null || lastKey.compareTo(maxKeyInDB) <= -1) { maxKeyInDB = FDates.max(maxKeyInDB, lastKey); } maxKeyInDBFromLoadFurtherValues = FDates.max(maxKeyInDBFromLoadFurtherValues, lastKey); if (furtherValues.size() > 1) { Assertions.checkState( firstKey.compareTo(lastKey) <= 0, "Not ascending sorted! At firstKey [%s] and lastKey [%s]", firstKey, lastKey); } }
private void pushLastValueFromFurtherValues() { while (lastValuesFromFurtherValues.size() >= MAX_LAST_VALUES_FROM_LOAD_FURTHER_VALUES) { lastValuesFromFurtherValues.next(); } lastValuesFromFurtherValues.add(furtherValues.next()); }
private V searchInFurtherValues(final FDate key) { // Take the first matching value from the sorted list // Search for the newest value V prevValue = (V) null; FDate prevKey = null; if (!lastValuesFromFurtherValues.isEmpty()) { // though maybe use the last one for smaller increments than the data itself is loaded for (final V lastValueFromFurtherValues : lastValuesFromFurtherValues) { final FDate keyLastValueFromFurtherValues = extractKey(key, lastValueFromFurtherValues); if (keyLastValueFromFurtherValues.isBeforeOrEqualTo(key)) { prevValue = lastValueFromFurtherValues; prevKey = keyLastValueFromFurtherValues; } else { // only go to further values if it might be possible that those are useable return prevValue; } } } final FDate earliestStartOfLoadFurtherValues = determineEaliestStartOfLoadFurtherValues(key); while (furtherValues.size() > 0) { final V newValue = furtherValues.getHead(); final FDate newValueKey = extractKey(key, newValue); final int compare = key.compareTo(newValueKey); if (compare < 0) { // key < newValueKey // run over the key we wanted break; } else if (compare == 0) { // key == newValueKey // This is the value we searched for! It will later be added with the db key to the cache. pushLastValueFromFurtherValues(); return newValue; } else { // key > newValueKey // put this value into the cache; gaps do not get filled here, so that the max size of the // cache does not get reached prematurely put(newValueKey, newValue, prevKey, prevValue); pushLastValueFromFurtherValues(); // continue with the next one prevValue = newValue; prevKey = newValueKey; if (furtherValues.isEmpty() && newValueKey.isBefore(maxKeyInDB) && key.isBefore(maxKeyInDB) && maxKeyInDBFromLoadFurtherValues.isBefore(maxKeyInDB)) { final FDate timeForLoadFurtherValues = FDates.max(newValueKey, earliestStartOfLoadFurtherValues); Assertions.checkState( eventuallyLoadFurtherValues( "searchInFurtherValues", newValueKey, timeForLoadFurtherValues, false, true)); if (!furtherValues.isEmpty()) { pushLastValueFromFurtherValues(); if (!timeForLoadFurtherValues.equals(newValue)) { // do not distort prev/next lookup when using earlisetStartOfLoadFurtherValues, thus // reset those prevValue = null; prevKey = null; } } } } } return prevValue; }