@Override
    public Optional<RefDataValue> getValue(final MapDefinition mapDefinition, final String key) {
        // try the KV store first

        Optional<RefDataValue> result;
        KeyValueMapKey keyValueMapKey = new KeyValueMapKey(mapDefinition, key);
        RefDataValue refDataValue = keyValueMap.get(keyValueMapKey);
        if (refDataValue != null) {
            result = Optional.of(refDataValue);
        } else {
            // not found in kv map so look in the range map
            try {
                // speculative lookup in the range store. At this point we don't know if we have
                // any ranges for this mapdef or not, but either way we need a call to LMDB so
                // just do the range lookup
                final long keyLong = Long.parseLong(key);

                // Look up our long key in the range store to see if it is part of a range.
                // It is possible for an event stream to have no associated context stream, or
                // the context stream may not contain the map and/or key requested in the lookup
                final NavigableMap<Range<Long>, RefDataValue> rangeSubMap = rangeValueNestedMap.get(mapDefinition);
                if (NullSafe.hasEntries(rangeSubMap)) {
                    result = getValueByRange(rangeSubMap, keyLong);
                } else {
                    result = Optional.empty();
                }

            } catch (NumberFormatException e) {
                // key could not be converted to a long, either this mapdef has no ranges or
                // an invalid key was used. See if we have any ranges at all for this mapdef
                // to determine whether to error or not.
                boolean doesStoreContainRanges = rangeValueNestedMap.containsKey(mapDefinition);
                if (doesStoreContainRanges) {
                    // we have ranges for this map def, so we would expect to be able to convert the key
                    throw new RuntimeException(LogUtil.message(
                            "Key {} cannot be used with the range store as it cannot be converted to a long",
                            key),
                            e);
                }
                // no ranges for this map def so the fact that we could not convert the key to a long
                // is not a problem. Do nothing.
                result = Optional.empty();
            }
        }
        final Optional<RefDataValue> result2 = result;
        LAMBDA_LOGGER.trace(() -> LogUtil.message("getValue({}, {}) returning {}", mapDefinition, key, result2));
        return result;
    }
A heap based implementation of the {@link RefDataStore}
that is intended for use with reference data with a very short life, i.e. context
data that is transient and only required for the life of a single pipeline processor
task. As such it is not thread safe and only intended to be used to by a single thread.
It also does not support purge operations as it is expected that the store will be created,
populated, used, then destroyed when no longer needed.
stroom-pipeline/src/main/java/stroom/pipeline/refdata/store/onheapstore/RefDataOnHeapStore.java