@Override
        public void createChildKeyRange(final Key parentKey,
                                        final TimeFilter timeFilter,
                                        final Consumer<KeyRange<ByteBuffer>> consumer) {
            if (timeFilter == null) {
                createChildKeyRange(parentKey, consumer);

            } else {
                KeyRange<ByteBuffer> keyRange;

                // If this is a grouping key then we need to add the depth first.
                final int depth = parentKey.getDepth();
                final byte childDepth = (byte) parentKey.getChildDepth();
                if (isDetailLevel(depth)) {
                    // This is a detail level - non-grouped row.
                    // Not valid for a parent key stem.
                    throw new RuntimeException("Invalid parent as detail key");

                } else if (depth == -1) {
                    final ByteBuffer start = byteBufferFactory.acquire(Byte.BYTES + Long.BYTES);
                    start.put(childDepth);
                    start.putLong(timeFilter.getFrom());
                    start.flip();
                    final ByteBuffer stop = byteBufferFactory.acquire(start.limit());
                    stop.put(childDepth);
                    stop.putLong(timeFilter.getTo() + 1);
                    stop.flip();
                    keyRange = KeyRange.closedOpen(start, stop);
                } else {
                    // Calculate all group hashes.
                    final long[] groupHashes = new long[parentKey.getKeyParts().size()];
                    int i = 0;
                    for (final KeyPart keyPart : parentKey.getKeyParts()) {
                        final GroupKeyPart groupKeyPart = (GroupKeyPart) keyPart;
                        final long groupHash = storedValueKeyFactory.hash(groupKeyPart.getGroupValues());
                        groupHashes[i++] = groupHash;
                    }

                    // Create a time based child group key. <DEPTH><TIME_MS><GROUP_HASHES...>
                    final ByteBuffer start = byteBufferFactory.acquire(
                            Byte.BYTES + Long.BYTES + (groupHashes.length * Long.BYTES));
                    start.put(childDepth);
                    start.putLong(timeFilter.getFrom());
                    for (final long groupHash : groupHashes) {
                        start.putLong(groupHash);
                    }
                    start.flip();
                    final ByteBuffer stop = byteBufferFactory.acquire(start.limit());
                    stop.put(childDepth);
                    stop.putLong(timeFilter.getTo());
                    if (groupHashes.length > 0) {
                        for (i = 0; i < groupHashes.length - 1; i++) {
                            stop.putLong(groupHashes[i]);
                        }
                        // Add final long that is one greater than the value we are looking to match.
                        stop.putLong(groupHashes[groupHashes.length - 1] + 1);
                    }
                    stop.flip();
                    keyRange = KeyRange.closedOpen(start, stop);
                }

                consumer.accept(keyRange);
            }
        }
Creates a nested time based group key. <DEPTH><TIME_MS><PARENT_GROUP_HASH><GROUP_HASH>
stroom-query/stroom-query-common/src/main/java/stroom/query/common/v2/LmdbRowKeyFactoryFactory.java