private void insert(final WriteTxn writeTxn,
                        final LmdbDb db,
                        final LmdbKV lmdbKV) {
        SearchProgressLog.increment(queryKey, SearchPhase.LMDB_DATA_STORE_INSERT);
        SimpleMetrics.measure("Insert", () -> {
            try {
                LOGGER.trace(() -> "insert");

                // Just try to put first.
                final boolean success = put(
                        writeTxn,
                        db,
                        lmdbKV.key(),
                        lmdbKV.val(),
                        PutFlags.MDB_NOOVERWRITE);
                if (success) {
                    resultCount.incrementAndGet();

                } else {
                    final int depth = lmdbRowKeyFactory.getDepth(lmdbKV);
                    if (lmdbRowKeyFactory.isGroup(depth)) {
                        final StoredValues newStoredValues = readValues(lmdbKV.val().duplicate());
                        final Val[] newGroupValues
                                = storedValueKeyFactory.getGroupValues(depth, newStoredValues);

                        // Get the existing entry for this key.
                        final ByteBuffer existingValueBuffer = db.get(writeTxn, lmdbKV.key());
                        final ByteBuffer newValueBuffer = lmdbRowValueFactory.useOutput(output -> {
                            boolean merged = false;
                            while (existingValueBuffer.remaining() > 0) {
                                final int startPos = existingValueBuffer.position();
                                final StoredValues existingStoredValues = readValues(existingValueBuffer);
                                final int endPos = existingValueBuffer.position();
                                final Val[] existingGroupValues
                                        = storedValueKeyFactory.getGroupValues(depth, existingStoredValues);

                                // If this is the same value then update it and reinsert.
                                if (Arrays.equals(existingGroupValues, newGroupValues)) {
                                    for (final CompiledColumn compiledColumn : compiledColumnArray) {
                                        compiledColumn.getGenerator().merge(existingStoredValues, newStoredValues);
                                    }

                                    LOGGER.trace(() -> "Merging combined value to output");
                                    try (final DataWriter writer = writerFactory.create(output)) {
                                        valueReferenceIndex.write(existingStoredValues, writer);
                                    }

                                    // Copy any remaining values.
                                    output.writeByteBuffer(existingValueBuffer);
                                    merged = true;
                                } else {
                                    LOGGER.debug(() -> "Copying value to output");
                                    output.writeByteBuffer(existingValueBuffer.slice(startPos, endPos - startPos));
                                }
                            }

                            // Append if we didn't merge.
                            if (!merged) {
                                LOGGER.debug(() -> "Appending value to output");
                                output.writeByteBuffer(lmdbKV.val());
                                resultCount.incrementAndGet();
                            }
                        });

                        final boolean ok = put(writeTxn, db, lmdbKV.key(), newValueBuffer);
                        bufferFactory.release(newValueBuffer);

                        if (!ok) {
                            LOGGER.debug(() -> "Unable to update");
                            throw new RuntimeException("Unable to update");
                        }

                    } else {
                        // We do not expect a key collision here.
                        final String message = "Unexpected collision (" +
                                               "key factory=" +
                                               keyFactory.getClass().getSimpleName() +
                                               ", " +
                                               "lmdbRowKeyFactory=" +
                                               lmdbRowKeyFactory.getClass().getSimpleName() +
                                               ")";
                        LOGGER.debug(message);
                        throw new RuntimeException(message);
                    }
                }

            } catch (final RuntimeException e) {
                error(e);
                if (LOGGER.isTraceEnabled()) {
                    // Only evaluate queue item value in trace as it can be expensive.
                    LOGGER.trace(() -> "Error putting " + lmdbKV + " (" + e.getMessage() + ")", e);
                } else {
                    LOGGER.debug(() -> "Error putting queueItem (" + e.getMessage() + ")", e);
                }

                error(new RuntimeException("Error adding data into search result store", e));
                throw e;

            } finally {
                // Release buffers back to the pool.
                bufferFactory.release(lmdbKV.key());
                bufferFactory.release(lmdbKV.val());
            }
        });
    }
Add some values to the data store.

@param values The values to add to the store.
stroom-query/stroom-query-common/src/main/java/stroom/query/common/v2/LmdbDataStore.java