private void migrateRefStreamDef(final RefStreamDefinition refStreamDefinition,
                                     final RefDataOffHeapStore destStore) {

        final DurationTimer timer = DurationTimer.start();
        // Here just to make code clearer
        // Need to lock both to ensure no one is trying to load the same stream into the dest store
        // or purge it from the source store. A deadlock is a bit of a worry as we are getting two locks
        // but this should be the only code that tries to lock the legacy store and a new one.
        updateTaskContextInfoSupplier("Waiting for destination store lock");
        destStore.doWithRefStreamDefinitionLock(refStreamDefinition, () -> {
            LOGGER.debug("Acquired destination lock in {}, refStreamDef: {}", timer, refStreamDefinition);
            updateTaskContextInfoSupplier("Waiting for source store lock");
            sourceStore.doWithRefStreamDefinitionLock(refStreamDefinition, () -> {
                LOGGER.debug("Acquired source lock in {}, refStreamDef: {}", timer, refStreamDefinition);

                // It is possible another thread beat us to the migration (or loaded it),
                // so check again for existence
                final boolean refStreamDefExists = destStore.exists(refStreamDefinition);
                if (refStreamDefExists) {
                    LOGGER.debug("refStreamDefinition already exists in destinationStore, nothing to do. " +
                            "refStreamDefinition: {}", refStreamDefinition);
                } else {
                    final Optional<RefDataProcessingInfo> optInfo = processingInfoDb.get(refStreamDefinition);
                    optInfo.ifPresent(info -> {
                        destStore.doWithLoaderUnlessComplete(
                                refStreamDefinition,
                                info.getEffectiveTimeEpochMs(),
                                refDataLoader -> {
                                    final OffHeapRefDataLoader destStoreLoader =
                                            (OffHeapRefDataLoader) refDataLoader;
                                    migrateRefStreamDef(refStreamDefinition, destStoreLoader);
                                });
                    });
                }
                // Now this stream is all migrated, mark as ready to purge so it is picked up in
                // purgePartialLoads
                LOGGER.info("Making ref stream available for purge: {}", refStreamDefinition);
                sourceStore.setProcessingState(refStreamDefinition, ProcessingState.READY_FOR_PURGE);
            });
        });
    }
Migrate the data for refStreamId into destinationStore
stroom-pipeline/src/main/java/stroom/pipeline/refdata/store/offheapstore/StoreMigrator.java