diff --git a/cmake/utils.cmake b/cmake/utils.cmake
index bdb43de097..9e09e51f16 100644
--- a/cmake/utils.cmake
+++ b/cmake/utils.cmake
@@ -53,9 +53,16 @@ function(fdb_find_sources out)
     LIST_DIRECTORIES false
     RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}/include"
     CONFIGURE_DEPENDS "include/*.cpp" "include/*.c" "include/*.h" "include/*.hpp")
+  file(GLOB_RECURSE res_workloads
+    LIST_DIRECTORIES false
+    RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}/workloads"
+    CONFIGURE_DEPENDS "workloads/*.cpp" "workloads/*.c" "workloads/*.h" "workloads/*.hpp")
 
   foreach(f IN LISTS res_includes)
     list(APPEND res "include/${f}")
   endforeach()
+  foreach(f IN LISTS res_workloads)
+    list(APPEND res "workloads/${f}")
+  endforeach()
   set(${out} "${res}" PARENT_SCOPE)
 endfunction()
diff --git a/contrib/CMakeLists.txt b/contrib/CMakeLists.txt
index d8bab140b8..1f47d60369 100644
--- a/contrib/CMakeLists.txt
+++ b/contrib/CMakeLists.txt
@@ -4,6 +4,7 @@ target_include_directories(rapidjson INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}/rapid
 add_subdirectory(crc32)
 add_subdirectory(stacktrace)
 add_subdirectory(folly_memcpy)
+add_subdirectory(sqlite)
 add_subdirectory(SimpleOpt)
 add_subdirectory(fmt-8.1.1)
 if(NOT WIN32)
diff --git a/contrib/sqlite/CMakeLists.txt b/contrib/sqlite/CMakeLists.txt
new file mode 100644
index 0000000000..b133664b5a
--- /dev/null
+++ b/contrib/sqlite/CMakeLists.txt
@@ -0,0 +1,16 @@
+add_library(sqlite STATIC
+  btree.h
+  hash.h
+  sqlite3.h
+  sqlite3ext.h
+  sqliteInt.h
+  sqliteLimit.h
+  sqlite3.amalgamation.c)
+
+
+target_include_directories(sqlite PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
+# Suppress warnings in sqlite since it's third party
+if(NOT WIN32)
+  target_compile_definitions(sqlite PRIVATE $<$<CONFIG:Debug>:NDEBUG>)
+  target_compile_options(sqlite BEFORE PRIVATE -w) # disable warnings for third party
+endif()
diff --git a/fdbserver/sqlite/btree.c b/contrib/sqlite/btree.c
similarity index 100%
rename from fdbserver/sqlite/btree.c
rename to contrib/sqlite/btree.c
diff --git a/fdbserver/sqlite/btree.h b/contrib/sqlite/btree.h
similarity index 100%
rename from fdbserver/sqlite/btree.h
rename to contrib/sqlite/btree.h
diff --git a/fdbserver/sqlite/hash.h b/contrib/sqlite/hash.h
similarity index 100%
rename from fdbserver/sqlite/hash.h
rename to contrib/sqlite/hash.h
diff --git a/fdbserver/sqlite/shell.c b/contrib/sqlite/shell.c
similarity index 100%
rename from fdbserver/sqlite/shell.c
rename to contrib/sqlite/shell.c
diff --git a/fdbserver/sqlite/sqlite3.amalgamation.c b/contrib/sqlite/sqlite3.amalgamation.c
similarity index 100%
rename from fdbserver/sqlite/sqlite3.amalgamation.c
rename to contrib/sqlite/sqlite3.amalgamation.c
diff --git a/fdbserver/sqlite/sqlite3.h b/contrib/sqlite/sqlite3.h
similarity index 100%
rename from fdbserver/sqlite/sqlite3.h
rename to contrib/sqlite/sqlite3.h
diff --git a/fdbserver/sqlite/sqlite3ext.h b/contrib/sqlite/sqlite3ext.h
similarity index 100%
rename from fdbserver/sqlite/sqlite3ext.h
rename to contrib/sqlite/sqlite3ext.h
diff --git a/fdbserver/sqlite/sqliteInt.h b/contrib/sqlite/sqliteInt.h
similarity index 100%
rename from fdbserver/sqlite/sqliteInt.h
rename to contrib/sqlite/sqliteInt.h
diff --git a/fdbserver/sqlite/sqliteLimit.h b/contrib/sqlite/sqliteLimit.h
similarity index 100%
rename from fdbserver/sqlite/sqliteLimit.h
rename to contrib/sqlite/sqliteLimit.h
diff --git a/fdbserver/CMakeLists.txt b/fdbserver/CMakeLists.txt
index 3388dfb7f0..6054b7c8dd 100644
--- a/fdbserver/CMakeLists.txt
+++ b/fdbserver/CMakeLists.txt
@@ -1,351 +1,11 @@
-set(FDBSERVER_SRCS
-  ApplyMetadataMutation.cpp
-  ApplyMetadataMutation.h
-  art.h
-  art_impl.h
-  ArtMutationBuffer.h
-  BackupInterface.h
-  BackupProgress.actor.cpp
-  BackupProgress.actor.h
-  BackupWorker.actor.cpp
-  BlobGranuleServerCommon.actor.cpp
-  BlobGranuleServerCommon.actor.h
-  BlobGranuleValidation.actor.cpp
-  BlobGranuleValidation.actor.h
-  BlobManager.actor.cpp
-  BlobManagerInterface.h
-  BlobWorker.actor.cpp
-  ClusterController.actor.cpp
-  ClusterController.actor.h
-  ClusterRecovery.actor.cpp
-  ClusterRecovery.actor.h
-  CommitProxyServer.actor.cpp
-  ConfigBroadcaster.actor.cpp
-  ConfigBroadcaster.h
-  ConfigBroadcastInterface.h
-  ConfigDatabaseUnitTests.actor.cpp
-  ConfigFollowerInterface.cpp
-  ConfigFollowerInterface.h
-  ConfigNode.actor.cpp
-  ConfigNode.h
-  ConflictSet.h
-  CoordinatedState.actor.cpp
-  CoordinatedState.h
-  Coordination.actor.cpp
-  CoordinationInterface.h
-  CoroFlow.h
-  DataDistribution.actor.cpp
-  DataDistribution.actor.h
-  DataDistributionQueue.actor.cpp
-  DataDistributionTracker.actor.cpp
-  DataDistributorInterface.h
-  DBCoreState.h
-  DDTeamCollection.actor.cpp
-  DDTeamCollection.h
-  DDTxnProcessor.h
-  DDTxnProcessor.actor.cpp
-  DeltaTree.h
-  DiskQueue.actor.cpp
-  EncryptKeyProxy.actor.cpp
-  EncryptKeyProxyInterface.h
-  FDBExecHelper.actor.cpp
-  FDBExecHelper.actor.h
-  fdbserver.actor.cpp
-  GetEncryptCipherKeys.actor.cpp
-  GetEncryptCipherKeys.h
-  GrvProxyServer.actor.cpp
-  IConfigConsumer.cpp
-  IConfigConsumer.h
-  IDiskQueue.h
-  IKeyValueContainer.h
-  IKeyValueStore.h
-  IPager.h
-  KeyValueStoreCompressTestData.actor.cpp
-  KeyValueStoreMemory.actor.cpp
-  KeyValueStoreRocksDB.actor.cpp
-  KeyValueStoreShardedRocksDB.actor.cpp
-  KeyValueStoreSQLite.actor.cpp
-  KmsConnector.h
-  KmsConnectorInterface.h
-  KnobProtectiveGroups.cpp
-  KnobProtectiveGroups.h
-  Knobs.h
-  LatencyBandConfig.cpp
-  LatencyBandConfig.h
-  LeaderElection.actor.cpp
-  LeaderElection.h
-  LocalConfiguration.actor.cpp
-  LocalConfiguration.h
-  LogProtocolMessage.h
-  LogRouter.actor.cpp
-  LogSystem.cpp
-  LogSystem.h
-  LogSystemConfig.cpp
-  LogSystemConfig.h
-  LogSystemDiskQueueAdapter.actor.cpp
-  LogSystemDiskQueueAdapter.h
-  LogSystemPeekCursor.actor.cpp
-  MasterInterface.h
-  masterserver.actor.cpp
-  MetricLogger.actor.cpp
-  MetricLogger.actor.h
-  MoveKeys.actor.cpp
-  MoveKeys.actor.h
-  MutationTracking.cpp
-  MutationTracking.h
-  networktest.actor.cpp
-  NetworkTest.h
-  OldTLogServer_4_6.actor.cpp
-  OldTLogServer_6_0.actor.cpp
-  OldTLogServer_6_2.actor.cpp
-  OTELSpanContextMessage.h
-  OnDemandStore.actor.cpp
-  OnDemandStore.h
-  PaxosConfigConsumer.actor.cpp
-  PaxosConfigConsumer.h
-  ProxyCommitData.actor.h
-  pubsub.actor.cpp
-  pubsub.h
-  QuietDatabase.actor.cpp
-  QuietDatabase.h
-  RadixTree.h
-  Ratekeeper.actor.cpp
-  Ratekeeper.h
-  RatekeeperInterface.h
-  RecoveryState.h
-  RemoteIKeyValueStore.actor.h
-  RemoteIKeyValueStore.actor.cpp
-  RESTKmsConnector.h
-  RESTKmsConnector.actor.cpp
-  ResolutionBalancer.actor.cpp
-  ResolutionBalancer.actor.h
-  Resolver.actor.cpp
-  ResolverInterface.h
-  RestoreApplier.actor.cpp
-  RestoreApplier.actor.h
-  RestoreCommon.actor.cpp
-  RestoreCommon.actor.h
-  RestoreController.actor.cpp
-  RestoreController.actor.h
-  RestoreLoader.actor.cpp
-  RestoreLoader.actor.h
-  RestoreRoleCommon.actor.cpp
-  RestoreRoleCommon.actor.h
-  RestoreUtil.actor.cpp
-  RestoreUtil.h
-  RestoreWorker.actor.cpp
-  RestoreWorker.actor.h
-  RestoreWorkerInterface.actor.cpp
-  RestoreWorkerInterface.actor.h
-  RkTagThrottleCollection.cpp
-  RkTagThrottleCollection.h
-  RocksDBCheckpointUtils.actor.cpp
-  RocksDBCheckpointUtils.actor.h
-  RoleLineage.actor.cpp
-  RoleLineage.actor.h
-  ServerCheckpoint.actor.cpp
-  ServerCheckpoint.actor.h
-  ServerDBInfo.actor.h
-  ServerDBInfo.h
-  SigStack.cpp
-  SimKmsConnector.h
-  SimKmsConnector.actor.cpp
-  SimpleConfigConsumer.actor.cpp
-  SimpleConfigConsumer.h
-  SimulatedCluster.actor.cpp
-  SimulatedCluster.h
-  SkipList.cpp
-  SpanContextMessage.h
-  Status.actor.cpp
-  Status.h
-  StorageCache.actor.cpp
-  StorageMetrics.actor.cpp
-  StorageMetrics.h
-  storageserver.actor.cpp
-  TagPartitionedLogSystem.actor.cpp
-  TagPartitionedLogSystem.actor.h
-  TagThrottler.actor.cpp
-  TagThrottler.h
-  TCInfo.actor.cpp
-  TCInfo.h
-  template_fdb.h
-  tester.actor.cpp
-  TenantCache.actor.cpp
-  TenantCache.h
-  TesterInterface.actor.h
-  TLogInterface.h
-  TLogServer.actor.cpp
-  TransactionTagCounter.cpp
-  TransactionTagCounter.h
-  TSSMappingUtil.actor.cpp
-  TSSMappingUtil.actor.h
-  VersionedBTree.actor.cpp
-  VFSAsync.cpp
-  VFSAsync.h
-  WaitFailure.actor.cpp
-  WaitFailure.h
-  worker.actor.cpp
-  WorkerInterface.actor.h
-  workloads/ApiCorrectness.actor.cpp
-  workloads/ApiWorkload.actor.cpp
-  workloads/ApiWorkload.h
-  workloads/AsyncFile.actor.h
-  workloads/AsyncFile.cpp
-  workloads/AsyncFileCorrectness.actor.cpp
-  workloads/AsyncFileRead.actor.cpp
-  workloads/AsyncFileWrite.actor.cpp
-  workloads/AtomicOps.actor.cpp
-  workloads/AtomicOpsApiCorrectness.actor.cpp
-  workloads/AtomicRestore.actor.cpp
-  workloads/AtomicSwitchover.actor.cpp
-  workloads/BackgroundSelectors.actor.cpp
-  workloads/BackupAndParallelRestoreCorrectness.actor.cpp
-  workloads/BackupCorrectness.actor.cpp
-  workloads/BackupToBlob.actor.cpp
-  workloads/BackupToDBAbort.actor.cpp
-  workloads/BackupToDBCorrectness.actor.cpp
-  workloads/BackupToDBUpgrade.actor.cpp
-  workloads/BlobGranuleCorrectnessWorkload.actor.cpp
-  workloads/BlobGranuleVerifier.actor.cpp
-  workloads/BlobStoreWorkload.h
-  workloads/BulkLoad.actor.cpp
-  workloads/BulkSetup.actor.h
-  workloads/Cache.actor.cpp
-  workloads/ChangeConfig.actor.cpp
-  workloads/ChangeFeeds.actor.cpp
-  workloads/ClearSingleRange.actor.cpp
-  workloads/ClientTransactionProfileCorrectness.actor.cpp
-  workloads/ClientWorkload.actor.cpp
-  workloads/ClogSingleConnection.actor.cpp
-  workloads/CommitBugCheck.actor.cpp
-  workloads/ConfigIncrement.actor.cpp
-  workloads/ConfigureDatabase.actor.cpp
-  workloads/ConflictRange.actor.cpp
-  workloads/ConsistencyCheck.actor.cpp
-  workloads/CpuProfiler.actor.cpp
-  workloads/Cycle.actor.cpp
-  workloads/DataDistributionMetrics.actor.cpp
-  workloads/DataLossRecovery.actor.cpp
-  workloads/DDBalance.actor.cpp
-  workloads/DDMetrics.actor.cpp
-  workloads/DDMetricsExclude.actor.cpp
-  workloads/DifferentClustersSameRV.actor.cpp
-  workloads/DiskDurability.actor.cpp
-  workloads/DiskDurabilityTest.actor.cpp
-  workloads/DiskFailureInjection.actor.cpp
-  workloads/DummyWorkload.actor.cpp
-  workloads/EncryptionOps.actor.cpp
-  workloads/EncryptKeyProxyTest.actor.cpp
-  workloads/ExternalWorkload.actor.cpp
-  workloads/FastTriggeredWatches.actor.cpp
-  workloads/FileSystem.actor.cpp
-  workloads/Fuzz.cpp
-  workloads/FuzzApiCorrectness.actor.cpp
-  workloads/GetMappedRange.actor.cpp
-  workloads/GetRangeStream.actor.cpp
-  workloads/HealthMetricsApi.actor.cpp
-  workloads/HighContentionPrefixAllocatorWorkload.actor.cpp
-  workloads/Increment.actor.cpp
-  workloads/IncrementalBackup.actor.cpp
-  workloads/IndexScan.actor.cpp
-  workloads/Inventory.actor.cpp
-  workloads/KillRegion.actor.cpp
-  workloads/KVStoreTest.actor.cpp
-  workloads/LocalRatekeeper.actor.cpp
-  workloads/LockDatabase.actor.cpp
-  workloads/LockDatabaseFrequently.actor.cpp
-  workloads/LogMetrics.actor.cpp
-  workloads/LowLatency.actor.cpp
-  workloads/MachineAttrition.actor.cpp
-  workloads/Mako.actor.cpp
-  workloads/MemoryKeyValueStore.cpp
-  workloads/MemoryKeyValueStore.h
-  workloads/MemoryLifetime.actor.cpp
-  workloads/MetricLogging.actor.cpp
-  workloads/MiniCycle.actor.cpp
-  workloads/MutationLogReaderCorrectness.actor.cpp
-  workloads/ParallelRestore.actor.cpp
-  workloads/Performance.actor.cpp
-  workloads/PhysicalShardMove.actor.cpp
-  workloads/Ping.actor.cpp
-  workloads/PopulateTPCC.actor.cpp
-  workloads/PrivateEndpoints.actor.cpp
-  workloads/ProtocolVersion.actor.cpp
-  workloads/PubSubMultiples.actor.cpp
-  workloads/QueuePush.actor.cpp
-  workloads/RandomClogging.actor.cpp
-  workloads/RandomMoveKeys.actor.cpp
-  workloads/RandomSelector.actor.cpp
-  workloads/ReadAfterWrite.actor.cpp
-  workloads/ReadHotDetection.actor.cpp
-  workloads/ReadWrite.actor.cpp
-  workloads/ReadWriteWorkload.actor.h
-  workloads/RemoveServersSafely.actor.cpp
-  workloads/ReportConflictingKeys.actor.cpp
-  workloads/RestoreBackup.actor.cpp
-  workloads/RestoreFromBlob.actor.cpp
-  workloads/Rollback.actor.cpp
-  workloads/RyowCorrectness.actor.cpp
-  workloads/RYWDisable.actor.cpp
-  workloads/RYWPerformance.actor.cpp
-  workloads/SaveAndKill.actor.cpp
-  workloads/SelectorCorrectness.actor.cpp
-  workloads/Serializability.actor.cpp
-  workloads/Sideband.actor.cpp
-  workloads/SidebandSingle.actor.cpp
-  workloads/SimpleAtomicAdd.actor.cpp
-  workloads/SkewedReadWrite.actor.cpp
-  workloads/SlowTaskWorkload.actor.cpp
-  workloads/SnapTest.actor.cpp
-  workloads/SpecialKeySpaceCorrectness.actor.cpp
-  workloads/StatusWorkload.actor.cpp
-  workloads/Storefront.actor.cpp
-  workloads/StreamingRangeRead.actor.cpp
-  workloads/StreamingRead.actor.cpp
-  workloads/SubmitBackup.actor.cpp
-  workloads/SuspendProcesses.actor.cpp
-  workloads/TagThrottleApi.actor.cpp
-  workloads/TargetedKill.actor.cpp
-  workloads/TaskBucketCorrectness.actor.cpp
-  workloads/TenantManagement.actor.cpp
-  workloads/ThreadSafety.actor.cpp
-  workloads/Throttling.actor.cpp
-  workloads/Throughput.actor.cpp
-  workloads/TimeKeeperCorrectness.actor.cpp
-  workloads/TPCC.actor.cpp
-  workloads/TPCCWorkload.h
-  workloads/TriggerRecovery.actor.cpp
-  workloads/UDPWorkload.actor.cpp
-  workloads/UnitPerf.actor.cpp
-  workloads/UnitTests.actor.cpp
-  workloads/Unreadable.actor.cpp
-  workloads/VersionStamp.actor.cpp
-  workloads/WatchAndWait.actor.cpp
-  workloads/Watches.actor.cpp
-  workloads/WatchesSameKeyCorrectness.actor.cpp
-  workloads/WorkerErrors.actor.cpp
-  workloads/workloads.actor.h
-  workloads/WriteBandwidth.actor.cpp
-  workloads/WriteDuringRead.actor.cpp
-  workloads/WriteTagThrottling.actor.cpp
-)
+fdb_find_sources(FDBSERVER_SRCS)
 
 if(${COROUTINE_IMPL} STREQUAL libcoro)
-  list(APPEND FDBSERVER_SRCS CoroFlowCoro.actor.cpp)
+  list(APPEND FDBSERVER_SRCS coroimpl/CoroFlowCoro.actor.cpp)
 else()
-  list(APPEND FDBSERVER_SRCS CoroFlow.actor.cpp)
+  list(APPEND FDBSERVER_SRCS coroimpl/CoroFlow.actor.cpp)
 endif()
 
-add_library(fdb_sqlite STATIC
-  sqlite/btree.h
-  sqlite/hash.h
-  sqlite/sqlite3.h
-  sqlite/sqlite3ext.h
-  sqlite/sqliteInt.h
-  sqlite/sqliteLimit.h
-  sqlite/sqlite3.amalgamation.c)
-target_include_directories(fdb_sqlite PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/sqlite)
-
 if (WITH_ROCKSDB_EXPERIMENTAL)
   add_definitions(-DSSD_ROCKSDB_EXPERIMENTAL)
 
@@ -359,12 +19,6 @@ if (WITH_ROCKSDB_EXPERIMENTAL)
   endif()
 endif()
 
-# Suppress warnings in sqlite since it's third party
-if(NOT WIN32)
-  target_compile_definitions(fdb_sqlite PRIVATE $<$<CONFIG:Debug>:NDEBUG>)
-  target_compile_options(fdb_sqlite BEFORE PRIVATE -w) # disable warnings for third party
-endif()
-
 file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/workloads)
 
 add_flow_target(EXECUTABLE NAME fdbserver SRCS ${FDBSERVER_SRCS})
@@ -372,21 +26,21 @@ add_flow_target(EXECUTABLE NAME fdbserver SRCS ${FDBSERVER_SRCS})
 target_include_directories(fdbserver PRIVATE
   ${CMAKE_SOURCE_DIR}/bindings/c
   ${CMAKE_BINARY_DIR}/bindings/c
-  ${CMAKE_CURRENT_BINARY_DIR}/workloads
-  ${CMAKE_CURRENT_SOURCE_DIR}/workloads)
+  ${CMAKE_CURRENT_SOURCE_DIR}/include
+  ${CMAKE_CURRENT_BINARY_DIR}/include)
 if (WITH_ROCKSDB_EXPERIMENTAL)
   add_dependencies(fdbserver rocksdb)
   if(WITH_LIBURING)
     target_include_directories(fdbserver PRIVATE ${ROCKSDB_INCLUDE_DIR} ${uring_INCLUDE_DIR})
-    target_link_libraries(fdbserver PRIVATE fdbclient fdb_sqlite ${ROCKSDB_LIBRARIES} ${uring_LIBRARIES} ${lz4_STATIC_LIBRARIES})
+    target_link_libraries(fdbserver PRIVATE fdbclient sqlite ${ROCKSDB_LIBRARIES} ${uring_LIBRARIES} ${lz4_STATIC_LIBRARIES})
     target_compile_definitions(fdbserver PRIVATE BOOST_ASIO_HAS_IO_URING=1 BOOST_ASIO_DISABLE_EPOLL=1)
   else()
     target_include_directories(fdbserver PRIVATE ${ROCKSDB_INCLUDE_DIR})
-    target_link_libraries(fdbserver PRIVATE fdbclient fdb_sqlite ${ROCKSDB_LIBRARIES} ${lz4_STATIC_LIBRARIES})
+    target_link_libraries(fdbserver PRIVATE fdbclient sqlite ${ROCKSDB_LIBRARIES} ${lz4_STATIC_LIBRARIES})
     target_compile_definitions(fdbserver PRIVATE)
   endif()
 else()
-  target_link_libraries(fdbserver PRIVATE fdbclient fdb_sqlite)
+  target_link_libraries(fdbserver PRIVATE fdbclient sqlite)
 endif()
 
 target_link_libraries(fdbserver PRIVATE toml11_target jemalloc rapidjson)
diff --git a/fdbserver/CompactMap.cpp b/fdbserver/CompactMap.cpp
deleted file mode 100644
index 1854cd4d6b..0000000000
--- a/fdbserver/CompactMap.cpp
+++ /dev/null
@@ -1,905 +0,0 @@
-/*
- * CompactMap.cpp
- *
- * This source file is part of the FoundationDB open source project
- *
- * Copyright 2013-2022 Apple Inc. and the FoundationDB project authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#pragma intrinsic(memcmp)
-
-#include "flow/flow.h"
-#include "flow/DeterministicRandom.h"
-#include "fdbserver/PrefixTree.h"
-#include <stdio.h>
-
-static int nextPowerOfTwo(int n) {
-	int p;
-	for (p = 1; p < n; p += p)
-		;
-	return p;
-}
-
-static int less(StringRef a, StringRef b) {
-	int al = a.size(), bl = b.size();
-	int cl = al < bl ? al : bl;
-	uint8_t const* ap = a.begin();
-	uint8_t const* bp = b.begin();
-	for (int i = 0; i < cl; i++) {
-		if (ap[i] < bp[i])
-			return 1;
-		else if (bp[i] < ap[i])
-			return 0;
-	}
-	return al < bl;
-}
-
-struct CompactPreOrderTree {
-	enum {
-		ENABLE_PREFETCH_RIGHT = 1
-	}; // Use rather more memory BW, but hide a little latency when a right branch takes us out of a cache line.  Seems
-	   // to help slightly.
-
-	struct Node {
-		enum { ENABLE_PREFIX = 1 }; // Enable or disable key prefix compression within a CompactPreOrderTree
-		enum { ENABLE_LEFT_PTR = 0 };
-
-		// offsets relative to `this`:
-		enum { KEY_LENGTH_OFFSET = ENABLE_PREFIX * 1 };
-		enum { KEY_DATA_OFFSET = KEY_LENGTH_OFFSET + 1 };
-
-		// offsets relative to `keyEnd()`:
-		enum { LPTR_OFFSET = 0 };
-		enum { RPTR_OFFSET = 2 * ENABLE_LEFT_PTR };
-		enum { END_OFFSET = RPTR_OFFSET + 2 };
-		enum { IMPLICIT_LPTR_VALUE = END_OFFSET };
-
-		static int getMaxOverhead() { return KEY_DATA_OFFSET + END_OFFSET; }
-
-		int keyPrefixLength() {
-			if (ENABLE_PREFIX)
-				return *(uint8_t*)this;
-			else
-				return 0;
-		}
-		int keyLength() { return *((uint8_t*)this + KEY_LENGTH_OFFSET); }
-		uint8_t const* keyData() { return (uint8_t const*)this + KEY_DATA_OFFSET; }
-		uint8_t const* keyEnd() { return (uint8_t const*)this + KEY_DATA_OFFSET + keyLength(); }
-		StringRef key() { return StringRef(keyData(), keyLength()); }
-		Node* left() {
-			auto ke = keyEnd();
-			return (Node*)(ke + (ENABLE_LEFT_PTR ? *(int16_t*)(ke + LPTR_OFFSET) : IMPLICIT_LPTR_VALUE));
-		}
-		Node* right() {
-			auto ke = keyEnd();
-			return (Node*)(ke + *(uint16_t*)(ke + RPTR_OFFSET));
-		}
-		uint8_t* getEnd() { return (uint8_t*)keyEnd() + END_OFFSET; }
-
-		void setKeyPrefixLength(int l) {
-			if (ENABLE_PREFIX) {
-				ASSERT(l < 256);
-				*(uint8_t*)this = l;
-			} else
-				ASSERT(!l);
-		}
-		void setKeyLength(int l) {
-			ASSERT(l < 256);
-			*((uint8_t*)this + KEY_LENGTH_OFFSET) = l;
-		}
-		void setLeftPointer(Node* ptr) {
-			auto ke = keyEnd();
-			int o = (uint8_t*)ptr - ke;
-			ASSERT(ENABLE_LEFT_PTR ? (int16_t(o) == o) : o == IMPLICIT_LPTR_VALUE);
-			if (ENABLE_LEFT_PTR)
-				*(uint16_t*)(ke + LPTR_OFFSET) = o;
-		}
-		void setRightPointer(Node* ptr) {
-			auto ke = keyEnd();
-			int o = (uint8_t*)ptr - ke;
-			ASSERT(-32768 <= o && o < 32767);
-			*(uint16_t*)(ke + RPTR_OFFSET) = o;
-		}
-	};
-
-	int nodeCount;
-	Node root;
-
-	int relAddr(Node* n) { return (uint8_t*)n - (uint8_t*)this; }
-
-	Node* lastLessOrEqual(StringRef searchKey) {
-		Node* n = &root; // n is the root of the subtree we are searching
-		Node* b = 0; // b is the greatest node <= searchKey which is a parent of n
-		int nBFIndex = 0; // the index of the node n in the entire tree in "breadth first order", i.e. level by level.
-		                  // This is NOT the order the tree is stored in!
-		int prefixSize = 0; // the number of bytes of searchKey which are equal to the first bytes of the logical key of
-		                    // the parent of n
-		int dir;
-
-		while (nBFIndex < nodeCount) {
-			int np = n->keyPrefixLength();
-			if (ENABLE_PREFETCH_RIGHT)
-				_mm_prefetch((const char*)n->right(), _MM_HINT_T0);
-			if (prefixSize < np) {
-				// The searchKey differs from this node's logical key in the prefix this node shares with its parent
-				// So the comparison between this node and searchKey has the same result as the comparison with the
-				// parent and searchKey (dir is unchanged)
-			} else {
-				// The searchKey is equal to this node's logical key up to the beginning of the compressed key
-				int al = searchKey.size() - np;
-				int bl = n->keyLength();
-				int cl = al < bl ? al : bl;
-				int prefixLen = commonPrefixLength(searchKey.begin() + np, n->keyData(), cl);
-				dir = prefixLen == cl ? al < bl : searchKey[np + prefixLen] < n->keyData()[prefixLen];
-				if (Node::ENABLE_PREFIX)
-					prefixSize = np + prefixLen;
-			}
-
-			nBFIndex = nBFIndex + nBFIndex + 2 - dir;
-			auto l = n->left(), r = n->right();
-			b = dir ? b : n;
-			n = dir ? l : r;
-		}
-
-		return b;
-	}
-
-	static std::pair<Node*, Node*> lastLessOrEqual2(CompactPreOrderTree* this1,
-	                                                CompactPreOrderTree* this2,
-	                                                StringRef searchKey1,
-	                                                StringRef searchKey2) {
-		// Do two separate lastLessOrEqual operations at once, to make better use of the memory subsystem.
-		// Don't try to read this code, it is write only (constructed by copy/paste from lastLessOrEqual and adding 1
-		// and 2 to variables as necessary)
-
-		Node* n1 = &this1->root; // n is the root of the subtree we are searching
-		Node* b1 = 0; // b is the greatest node <= searchKey which is a parent of n
-		int nBFIndex1 = 0; // the index of the node n in the entire tree in "breadth first order", i.e. level by level.
-		                   // This is NOT the order the tree is stored in!
-		int prefixSize1 = 0; // the number of bytes of searchKey which are equal to the first bytes of the logical key
-		                     // of the parent of n
-		int dir1;
-
-		Node* n2 = &this2->root; // n is the root of the subtree we are searching
-		Node* b2 = 0; // b is the greatest node <= searchKey which is a parent of n
-		int nBFIndex2 = 0; // the index of the node n in the entire tree in "breadth first order", i.e. level by level.
-		                   // This is NOT the order the tree is stored in!
-		int prefixSize2 = 0; // the number of bytes of searchKey which are equal to the first bytes of the logical key
-		                     // of the parent of n
-		int dir2;
-
-		while (nBFIndex1 < this1->nodeCount && nBFIndex2 < this2->nodeCount) {
-			int np1 = n1->keyPrefixLength();
-			int np2 = n2->keyPrefixLength();
-			if (ENABLE_PREFETCH_RIGHT) {
-				_mm_prefetch((const char*)n1->right(), _MM_HINT_T0);
-				_mm_prefetch((const char*)n2->right(), _MM_HINT_T0);
-			}
-			if (prefixSize1 < np1) {
-				// The searchKey differs from this node's logical key in the prefix this node shares with its parent
-				// So the comparison between this node and searchKey has the same result as the comparison with the
-				// parent and searchKey (dir is unchanged)
-			} else {
-				// The searchKey is equal to this node's logical key up to the beginning of the compressed key
-				int al1 = searchKey1.size() - np1;
-				int bl1 = n1->keyLength();
-				int cl1 = al1 < bl1 ? al1 : bl1;
-				int prefixLen1 = commonPrefixLength(searchKey1.begin() + np1, n1->keyData(), cl1);
-				dir1 = prefixLen1 == cl1 ? al1 < bl1 : searchKey1[np1 + prefixLen1] < n1->keyData()[prefixLen1];
-				prefixSize1 = np1 + prefixLen1;
-			}
-			if (prefixSize2 < np2) {
-				// The searchKey differs from this node's logical key in the prefix this node shares with its parent
-				// So the comparison between this node and searchKey has the same result as the comparison with the
-				// parent and searchKey (dir is unchanged)
-			} else {
-				// The searchKey is equal to this node's logical key up to the beginning of the compressed key
-				int al2 = searchKey2.size() - np2;
-				int bl2 = n2->keyLength();
-				int cl2 = al2 < bl2 ? al2 : bl2;
-				int prefixLen2 = commonPrefixLength(searchKey2.begin() + np2, n2->keyData(), cl2);
-				dir2 = prefixLen2 == cl2 ? al2 < bl2 : searchKey2[np2 + prefixLen2] < n2->keyData()[prefixLen2];
-				prefixSize2 = np2 + prefixLen2;
-			}
-
-			nBFIndex1 = nBFIndex1 + nBFIndex1 + 2 - dir1;
-			nBFIndex2 = nBFIndex2 + nBFIndex2 + 2 - dir2;
-			auto l1 = n1->left(), r1 = n1->right();
-			auto l2 = n2->left(), r2 = n2->right();
-			b1 = dir1 ? b1 : n1;
-			b2 = dir2 ? b2 : n2;
-			n1 = dir1 ? l1 : r1;
-			n2 = dir2 ? l2 : r2;
-		}
-
-		while (nBFIndex1 < this1->nodeCount) {
-			int np1 = n1->keyPrefixLength();
-			if (prefixSize1 < np1) {
-				// The searchKey differs from this node's logical key in the prefix this node shares with its parent
-				// So the comparison between this node and searchKey has the same result as the comparison with the
-				// parent and searchKey (dir is unchanged)
-			} else {
-				// The searchKey is equal to this node's logical key up to the beginning of the compressed key
-				int al1 = searchKey1.size() - np1;
-				int bl1 = n1->keyLength();
-				int cl1 = al1 < bl1 ? al1 : bl1;
-				int prefixLen1 = commonPrefixLength(searchKey1.begin() + np1, n1->keyData(), cl1);
-				dir1 = prefixLen1 == cl1 ? al1 < bl1 : searchKey1[np1 + prefixLen1] < n1->keyData()[prefixLen1];
-				prefixSize1 = np1 + prefixLen1;
-			}
-			nBFIndex1 = nBFIndex1 + nBFIndex1 + 2 - dir1;
-			auto l1 = n1->left(), r1 = n1->right();
-			b1 = dir1 ? b1 : n1;
-			n1 = dir1 ? l1 : r1;
-		}
-
-		while (nBFIndex2 < this2->nodeCount) {
-			int np2 = n2->keyPrefixLength();
-			if (prefixSize2 < np2) {
-				// The searchKey differs from this node's logical key in the prefix this node shares with its parent
-				// So the comparison between this node and searchKey has the same result as the comparison with the
-				// parent and searchKey (dir is unchanged)
-			} else {
-				// The searchKey is equal to this node's logical key up to the beginning of the compressed key
-				int al2 = searchKey2.size() - np2;
-				int bl2 = n2->keyLength();
-				int cl2 = al2 < bl2 ? al2 : bl2;
-				int prefixLen2 = commonPrefixLength(searchKey2.begin() + np2, n2->keyData(), cl2);
-				dir2 = prefixLen2 == cl2 ? al2 < bl2 : searchKey2[np2 + prefixLen2] < n2->keyData()[prefixLen2];
-				prefixSize2 = np2 + prefixLen2;
-			}
-			nBFIndex2 = nBFIndex2 + nBFIndex2 + 2 - dir2;
-			auto l2 = n2->left(), r2 = n2->right();
-			b2 = dir2 ? b2 : n2;
-			n2 = dir2 ? l2 : r2;
-		}
-
-		return std::make_pair(b1, b2);
-	}
-
-#if 0
-	enum { ENABLE_FANCY_BUILD=1 };
-
-	struct BuildInfo {
-		Node* parent;
-		bool rightChild;
-		std::string const& prefix;
-		std::string* begin;
-		std::string* end;
-		BuildInfo(Node* parent, bool rightChild, std::string const& prefix, std::string* begin, std::string* end)
-			: parent(parent), rightChild(rightChild), prefix(prefix), begin(begin), end(end) {}
-	};
-
-	int build(std::vector<std::string>& input, std::string const& prefix = std::string()) {
-		nodeCount = input.size();
-
-		Deque< BuildInfo > queue;
-		Deque< BuildInfo > deferred;
-		queue.push_back(BuildInfo(nullptr, false, prefix, &input[0], &input[0] + input.size()));
-
-		Node* node = &root;
-		uint8_t* cacheLineEnd = (uint8_t*)node + 64;
-		while (queue.size() || deferred.size()) {
-			if (!queue.size()) {
-				for (int i = 0; i < deferred.size(); i++)
-					queue.push_back( deferred[i] );
-				deferred.clear();
-			}
-			BuildInfo bi = queue.front();
-			queue.pop_front();
-
-			int mid = perfectSubtreeSplitPoint(bi.end - bi.begin);
-			std::string& s = bi.begin[mid];
-			int prefixLen = Node::ENABLE_PREFIX ? commonPrefixLength((uint8_t*)&bi.prefix[0], (uint8_t*)&s[0], std::min(bi.prefix.size(), s.size())) : 0;
-			node->setKeyPrefixLength(prefixLen);
-			node->setKeyLength(s.size() - prefixLen);
-			memcpy((uint8_t*)node->key().begin(), &s[prefixLen], s.size() - prefixLen);
-
-			if (bi.parent) {
-				if (bi.rightChild)
-					bi.parent->setRightPointer(node);
-				else
-					bi.parent->setLeftPointer(node);
-			}
-
-			if ((uint8_t*)node->getEnd() > cacheLineEnd) {
-				cacheLineEnd = (uint8_t*)((intptr_t)node->getEnd() &~63) + 64;
-				for (int i = 0; i < queue.size(); i++)
-					deferred.push_back(queue[i]);
-				queue.clear();
-			}
-
-			if (bi.begin != bi.begin + mid)
-				queue.push_back(BuildInfo(node, false, s, bi.begin, bi.begin + mid));
-			else if (Node::ENABLE_LEFT_PTR)
-				node->setLeftPointer(node);
-
-			if (bi.begin + mid + 1 != bi.end)
-				queue.push_back(BuildInfo(node, true, s, bi.begin + mid + 1, bi.end));
-			else
-				node->setRightPointer(node);
-
-			node = (Node*)node->getEnd();
-		}
-
-		return (uint8_t*)node - (uint8_t*)this;
-	}
-
-#else
-	enum { ENABLE_FANCY_BUILD = 0 };
-
-	int build(std::vector<std::string>& input, std::string const& prefix = std::string()) {
-		nodeCount = input.size();
-		return (uint8_t*)build(root, prefix, &input[0], &input[0] + input.size()) - (uint8_t*)this;
-	}
-	Node* build(Node& node, std::string const& prefix, std::string* begin, std::string* end) {
-		if (begin == end)
-			return &node;
-		int mid = perfectSubtreeSplitPoint(end - begin);
-		std::string& s = begin[mid];
-		int prefixLen =
-		    Node::ENABLE_PREFIX
-		        ? commonPrefixLength((uint8_t*)&prefix[0], (uint8_t*)&s[0], std::min(prefix.size(), s.size()))
-		        : 0;
-		// printf("Node: %s at %d, subtree size %d, mid=%d, prefix %d\n", s.c_str(), relAddr(&node), end-begin, mid,
-		// prefixLen);
-		node.setKeyPrefixLength(prefixLen);
-		node.setKeyLength(s.size() - prefixLen);
-		memcpy((uint8_t*)node.key().begin(), &s[prefixLen], s.size() - prefixLen);
-
-		Node* next = (Node*)node.getEnd();
-		if (begin != begin + mid) {
-			node.setLeftPointer(next);
-			next = build(*node.left(), s, begin, begin + mid);
-		} else if (Node::ENABLE_LEFT_PTR)
-			node.setLeftPointer(&node);
-
-		if (begin + mid + 1 != end) {
-			node.setRightPointer(next);
-			next = build(*node.right(), s, begin + mid + 1, end);
-		} else
-			node.setRightPointer(&node);
-
-		return next;
-	}
-#endif
-};
-
-void compactMapTests(std::vector<std::string> testData,
-                     std::vector<std::string> sampleQueries,
-                     std::string prefixTreeDOTFile = "") {
-	double t1, t2;
-	int r = 0;
-	std::sort(testData.begin(), testData.end());
-
-	/*for (int i = 0; i < testData.size() - 1; i++) {
-	    ASSERT(testData[i + 1].substr(0, 4) != testData[i].substr(0, 4));
-	    ASSERT(_byteswap_ulong(*(uint32_t*)&testData[i][0]) < _byteswap_ulong(*(uint32_t*)&testData[i + 1][0]));
-	}*/
-
-	int totalKeyBytes = 0;
-	for (auto& s : testData)
-		totalKeyBytes += s.size();
-	printf("%d bytes in %lu keys\n", totalKeyBytes, testData.size());
-
-	for (int i = 0; i < 5; i++)
-		printf("  '%s'\n", printable(StringRef(testData[i])).c_str());
-
-	CompactPreOrderTree* t =
-	    (CompactPreOrderTree*)new uint8_t[sizeof(CompactPreOrderTree) + totalKeyBytes +
-	                                      CompactPreOrderTree::Node::getMaxOverhead() * testData.size()];
-
-	t1 = timer_monotonic();
-	int compactTreeBytes = t->build(testData);
-	t2 = timer_monotonic();
-
-	printf("Compact tree is %d bytes\n", compactTreeBytes);
-	printf("Build time %0.0f us (%0.2f M/sec)\n", (t2 - t1) * 1e6, 1 / (t2 - t1) / 1e6);
-
-	t1 = timer_monotonic();
-	const int nBuild = 20000;
-	for (int i = 0; i < nBuild; i++)
-		r += t->build(testData);
-	t2 = timer_monotonic();
-	printf("Build time %0.0f us (%0.2f M/sec)\n", (t2 - t1) / nBuild * 1e6, nBuild / (t2 - t1) / 1e6);
-
-	PrefixTree* pt = (PrefixTree*)new uint8_t[sizeof(PrefixTree) + totalKeyBytes +
-	                                          testData.size() * PrefixTree::Node::getMaxOverhead(1, 256, 256)];
-
-	std::vector<PrefixTree::EntryRef> keys;
-	for (auto& k : testData) {
-		keys.emplace_back(k, StringRef());
-	}
-
-	t1 = timer_monotonic();
-	int prefixTreeBytes = pt->build(&*keys.begin(), &*keys.end(), StringRef(), StringRef());
-	t2 = timer_monotonic();
-
-	if (!prefixTreeDOTFile.empty()) {
-		FILE* fout = fopen(prefixTreeDOTFile.c_str(), "w");
-		fprintf(fout, "%s\n", pt->toDOT(StringRef(), StringRef()).c_str());
-		fclose(fout);
-	}
-
-	// Calculate perfect prefix-compressed size
-	int perfectSize = testData.front().size();
-	for (int i = 1; i < testData.size(); ++i) {
-		int common = commonPrefixLength(StringRef(testData[i]), StringRef(testData[i - 1]));
-		perfectSize += (testData[i].size() - common);
-	}
-
-	printf("PrefixTree tree is %d bytes\n", prefixTreeBytes);
-	printf("Perfect compressed size with no overhead is %d, average PrefixTree overhead is %.2f per item\n",
-	       perfectSize,
-	       double(prefixTreeBytes - perfectSize) / testData.size());
-	printf("PrefixTree Build time %0.0f us (%0.2f M/sec)\n", (t2 - t1) * 1e6, 1 / (t2 - t1) / 1e6);
-
-	// Test cursor forward iteration
-	auto c = pt->getCursor(StringRef(), StringRef());
-	ASSERT(c.moveFirst());
-
-	bool end = false;
-	for (int i = 0; i < keys.size(); ++i) {
-		ASSERT(c.getKeyRef() == keys[i].key);
-		end = !c.moveNext();
-	}
-	ASSERT(end);
-	printf("PrefixTree forward scan passed\n");
-
-	// Test cursor backward iteration
-	ASSERT(c.moveLast());
-
-	for (int i = keys.size() - 1; i >= 0; --i) {
-		ASSERT(c.getKeyRef() == keys[i].key);
-		end = !c.movePrev();
-	}
-	ASSERT(end);
-	printf("PrefixTree reverse scan passed\n");
-
-	t1 = timer_monotonic();
-	for (int i = 0; i < nBuild; i++)
-		r += pt->build(&*keys.begin(), &*keys.end(), StringRef(), StringRef());
-	t2 = timer_monotonic();
-	printf("PrefixTree Build time %0.0f us (%0.2f M/sec)\n", (t2 - t1) / nBuild * 1e6, nBuild / (t2 - t1) / 1e6);
-
-	t->lastLessOrEqual(LiteralStringRef("8f9fad2e5e2af980a"));
-
-	{
-		std::string s, s1;
-		CompactPreOrderTree::Node* n;
-		for (int i = 0; i < testData.size(); i++) {
-			s = testData[i];
-
-			auto s1 = s; // s.substr(0, s.size() - 1);
-			if (!s1.back())
-				s1 = s1.substr(0, s1.size() - 1);
-			else {
-				s1.back()--;
-				s1 += "\xff\xff\xff\xff\xff\xff";
-			}
-			auto n = t->lastLessOrEqual(s1);
-			// printf("lastLessOrEqual(%s) = %s\n", s1.c_str(), n ? n->key().toString().c_str() : "(null)");
-			ASSERT(i ? testData[i - 1].substr(n->keyPrefixLength()) == n->key() : !n);
-			n = t->lastLessOrEqual(s);
-			// printf("lastLessOrEqual(%s) = %s\n", s.c_str(), n ? n->key().toString().c_str() : "(null)");
-			ASSERT(n->key() == s.substr(n->keyPrefixLength()));
-			s1 = s + "a";
-			auto n1 = t->lastLessOrEqual(s1);
-			// printf("lastLessOrEqual(%s) = %s\n", s1.c_str(), n ? n->key().toString().c_str() : "(null)");
-			ASSERT(n1->key() == s.substr(n1->keyPrefixLength()));
-
-			ASSERT(CompactPreOrderTree::lastLessOrEqual2(t, t, s, s1) == std::make_pair(n, n1));
-		}
-		printf("compactMap lastLessOrEqual tests passed\n");
-	}
-
-	{
-		auto cur = pt->getCursor(StringRef(), StringRef());
-
-		for (int i = 0; i < keys.size(); i++) {
-			StringRef s = keys[i].key;
-
-			ASSERT(cur.seekLessThanOrEqual(s));
-			ASSERT(cur.valid());
-			ASSERT(cur.getKey() == s);
-
-			StringRef shortString = s.substr(0, s.size() - 1);
-			bool shorter = cur.seekLessThanOrEqual(shortString);
-			if (i > 0) {
-				if (shortString >= keys[i - 1].key) {
-					ASSERT(shorter);
-					ASSERT(cur.valid());
-					ASSERT(cur.getKey() == keys[i - 1].key);
-				}
-			} else {
-				ASSERT(!shorter);
-			}
-
-			ASSERT(cur.seekLessThanOrEqual(s.toString() + '\0'));
-			ASSERT(cur.valid());
-			ASSERT(cur.getKey() == s);
-		}
-		printf("PrefixTree lastLessOrEqual tests passed\n");
-	}
-
-	printf("Making %lu copies:\n", 2 * sampleQueries.size());
-
-	std::vector<CompactPreOrderTree*> copies;
-	for (int i = 0; i < 2 * sampleQueries.size(); i++) {
-		copies.push_back((CompactPreOrderTree*)new uint8_t[compactTreeBytes]);
-		memcpy(copies.back(), t, compactTreeBytes);
-	}
-	deterministicRandom()->randomShuffle(copies);
-
-	std::vector<PrefixTree*> prefixTreeCopies;
-	for (int i = 0; i < 2 * sampleQueries.size(); i++) {
-		prefixTreeCopies.push_back((PrefixTree*)new uint8_t[prefixTreeBytes]);
-		memcpy(prefixTreeCopies.back(), pt, prefixTreeBytes);
-	}
-	deterministicRandom()->randomShuffle(prefixTreeCopies);
-
-	std::vector<std::vector<std::string>> array_copies;
-	for (int i = 0; i < sampleQueries.size(); i++) {
-		array_copies.push_back(testData);
-	}
-	deterministicRandom()->randomShuffle(array_copies);
-
-	printf("shuffled\n");
-
-	t1 = timer_monotonic();
-	for (auto& q : sampleQueries)
-		r += (intptr_t)t->lastLessOrEqual(q);
-	t2 = timer_monotonic();
-	printf("compactmap, in cache: %d queries in %0.3f sec: %0.3f M/sec\n",
-	       (int)sampleQueries.size(),
-	       t2 - t1,
-	       sampleQueries.size() / (t2 - t1) / 1e6);
-
-	auto cur = pt->getCursor(StringRef(), StringRef());
-
-	t1 = timer_monotonic();
-	for (auto& q : sampleQueries)
-		r += cur.seekLessThanOrEqual(StringRef(q)) ? 1 : 0;
-	t2 = timer_monotonic();
-	printf("prefixtree, in cache: %d queries in %0.3f sec: %0.3f M/sec\n",
-	       (int)sampleQueries.size(),
-	       t2 - t1,
-	       sampleQueries.size() / (t2 - t1) / 1e6);
-
-	/*	t1 = timer_monotonic();
-	    for (int q = 0; q < sampleQueries.size(); q += 2) {
-	        auto x = CompactPreOrderTree::lastLessOrEqual2(t, t, sampleQueries[q], sampleQueries[q + 1]);
-	        r += (intptr_t)x.first + (intptr_t)x.second;
-	    }
-	    t2 = timer_monotonic();
-	    printf("in cache (2x interleaved): %d queries in %0.3f sec: %0.3f M/sec\n", (int)sampleQueries.size(), t2 - t1,
-	   sampleQueries.size() / (t2 - t1) / 1e6);
-	*/
-
-	t1 = timer_monotonic();
-	for (int q = 0; q < sampleQueries.size(); q++)
-		r += (intptr_t)copies[q]->lastLessOrEqual(sampleQueries[q]);
-	t2 = timer_monotonic();
-	printf("compactmap, out of cache: %d queries in %0.3f sec: %0.3f M/sec\n",
-	       (int)sampleQueries.size(),
-	       t2 - t1,
-	       sampleQueries.size() / (t2 - t1) / 1e6);
-
-	std::vector<PrefixTree::Cursor> cursors;
-	for (int q = 0; q < sampleQueries.size(); q++)
-		cursors.push_back(prefixTreeCopies[q]->getCursor(StringRef(), StringRef()));
-
-	t1 = timer_monotonic();
-	for (int q = 0; q < sampleQueries.size(); q++)
-		r += cursors[q].seekLessThanOrEqual(sampleQueries[q]) ? 1 : 0;
-	t2 = timer_monotonic();
-	printf("prefixtree, out of cache: %d queries in %0.3f sec: %0.3f M/sec\n",
-	       (int)sampleQueries.size(),
-	       t2 - t1,
-	       sampleQueries.size() / (t2 - t1) / 1e6);
-
-	/*
-	    t1 = timer_monotonic();
-	    for (int q = 0; q < sampleQueries.size(); q += 2) {
-	        auto x = CompactPreOrderTree::lastLessOrEqual2(copies[q + sampleQueries.size()], copies[q +
-	   sampleQueries.size() + 1], sampleQueries[q], sampleQueries[q + 1]); r += (intptr_t)x.first + (intptr_t)x.second;
-	    }
-	    t2 = timer_monotonic();
-	    printf("out of cache (2x interleaved): %d queries in %0.3f sec: %0.3f M/sec\n", (int)sampleQueries.size(), t2 -
-	   t1, sampleQueries.size() / (t2 - t1) / 1e6);
-	*/
-
-	t1 = timer_monotonic();
-	for (int q = 0; q < sampleQueries.size(); q++)
-		r += (intptr_t)(std::lower_bound(array_copies[q].begin(), array_copies[q].end(), sampleQueries[q]) -
-		                testData.begin());
-	t2 = timer_monotonic();
-	printf("std::lower_bound: %d queries in %0.3f sec: %0.3f M/sec\n",
-	       (int)sampleQueries.size(),
-	       t2 - t1,
-	       sampleQueries.size() / (t2 - t1) / 1e6);
-}
-
-std::vector<std::string> sampleDocuments(int N) {
-	std::vector<std::string> testData;
-	std::string p = "pre";
-	std::string n = "\x01"
-	                "name\x00\x00";
-	std::string a = "\x01"
-	                "address\x00\x00";
-	std::string o = "\x01"
-	                "orders\x00\x00";
-	std::string oi = "\x01"
-	                 "id\x00\x00";
-	std::string oa = "\x01"
-	                 "amount\x00\x00";
-	std::string dbl = "\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00";
-	for (int i = 0; i < N; i++) {
-		std::string id =
-		    BinaryWriter::toValue(deterministicRandom()->randomUniqueID(), Unversioned()).substr(12).toString();
-		testData.push_back(p + id + n);
-		testData.push_back(p + id + a);
-		for (int j = 0; j < 5; j++) {
-			std::string okey = p + id + o + dbl + (char)j;
-			testData.push_back(okey + oi);
-			testData.push_back(okey + oa);
-		}
-	}
-	return testData;
-}
-
-StringRef shortestKeyBetween(StringRef a, StringRef b) {
-	int p = commonPrefixLength(a.begin(), b.begin(), std::min(a.size(), b.size()));
-	ASSERT(p < b.size());
-	return b.substr(0, p + 1);
-}
-
-std::vector<std::string> sampleBPlusTreeSeparators(std::vector<std::string> rawDocs, int prefixToStrip) {
-	// In the middle of a B+Tree, we won't have adjacent document keys but separators between
-	// pages.  These need only contain as many bytes as necessary to distinguish the last item
-	// in the previous page and the first item in the next page ("suffix compression"), and when
-	// balancing the tree we can move a few keys left or right if it makes a big difference in the
-	// suffix size ("split interval")
-	// The B+Tree will presumably also do its own prefix compression, so we trim off the "obvious"
-	// common prefix for this imaginary middle node
-
-	std::vector<std::string> testData;
-	std::sort(rawDocs.begin(), rawDocs.end());
-	for (int i = 0; i + 1 < rawDocs.size(); i += 1000) {
-		StringRef bestSplitPoint = shortestKeyBetween(rawDocs[i], rawDocs[i + 1]);
-
-		for (int j = i + 1; j < i + 11; j++) {
-			StringRef s = shortestKeyBetween(rawDocs[j], rawDocs[j + 1]);
-			if (s.size() < bestSplitPoint.size())
-				bestSplitPoint = s;
-		}
-
-		testData.push_back(bestSplitPoint.substr(prefixToStrip).toString());
-	}
-	return testData;
-}
-
-struct Page {
-	Page() : tree(nullptr), size(0), sizeBuilt(0), unsortedKeys(0) {}
-
-	std::vector<PrefixTree::EntryRef> keys;
-	PrefixTree* tree;
-	std::string treeBuffer;
-	int size;
-	int sizeBuilt;
-	int unsortedKeys;
-
-	void add(StringRef k) {
-		keys.emplace_back(k, StringRef());
-		size += k.size();
-		++unsortedKeys;
-	}
-
-	void sort() {
-		static auto cmp = [=](const PrefixTree::EntryRef& a, const PrefixTree::EntryRef& b) { return a.key < b.key; };
-		if (unsortedKeys > 0) {
-			// sort newest elements, then merge
-			std::sort(keys.end() - unsortedKeys, keys.end(), cmp);
-			std::inplace_merge(keys.begin(), keys.end() - unsortedKeys, keys.end(), cmp);
-			unsortedKeys = 0;
-		}
-	}
-
-	int build() {
-		if (sizeBuilt != size) {
-			sort();
-			treeBuffer.reserve(keys.size() * PrefixTree::Node::getMaxOverhead(1, 256, 256) + size);
-			tree = (PrefixTree*)treeBuffer.data();
-			int b = tree->build(&*keys.begin(), &*keys.end(), StringRef(), StringRef());
-			sizeBuilt = size;
-			return b;
-		}
-		return 0;
-	}
-};
-
-void ingestBenchmark() {
-	std::vector<StringRef> keys_generated;
-	Arena arena;
-	std::set<StringRef> testmap;
-	for (int i = 0; i < 1000000; ++i) {
-		keys_generated.push_back(StringRef(arena,
-		                                   format("........%02X......%02X.....%02X........%02X",
-		                                          deterministicRandom()->randomInt(0, 100),
-		                                          deterministicRandom()->randomInt(0, 100),
-		                                          deterministicRandom()->randomInt(0, 100),
-		                                          deterministicRandom()->randomInt(0, 100))));
-	}
-
-	double t1 = timer_monotonic();
-	for (const auto& k : keys_generated)
-		testmap.insert(k);
-	double t2 = timer_monotonic();
-	printf("Ingested %d elements into map, Speed %f M/s\n",
-	       (int)keys_generated.size(),
-	       keys_generated.size() / (t2 - t1) / 1e6);
-
-	// sort a group after k elements were added
-	for (int k = 5; k <= 20; k += 5) {
-		// g is average page delta size
-		for (int g = 10; g <= 150; g += 10) {
-			// rebuild page after r bytes added
-			for (int r = 500; r <= 4000; r += 500) {
-				double elapsed = timer_monotonic();
-				int builds = 0;
-				int buildbytes = 0;
-				int keybytes = 0;
-
-				std::vector<Page*> pages;
-				int pageCount = keys_generated.size() / g;
-				pages.resize(pageCount);
-
-				for (auto& key : keys_generated) {
-					int p = deterministicRandom()->randomInt(0, pageCount);
-					Page*& pPage = pages[p];
-					if (pPage == nullptr)
-						pPage = new Page();
-					Page& page = *pPage;
-
-					page.add(key);
-					keybytes += key.size();
-
-					if (page.keys.size() % k == 0) {
-						page.sort();
-					}
-
-					// Rebuild page after r bytes added
-					if (page.size - page.sizeBuilt > r) {
-						int b = page.build();
-						if (b > 0) {
-							++builds;
-							buildbytes += b;
-						}
-					}
-				}
-
-				for (auto p : pages) {
-					if (p) {
-						int b = p->build();
-						if (b > 0) {
-							++builds;
-							buildbytes += b;
-						}
-					}
-				}
-
-				elapsed = timer_monotonic() - elapsed;
-				printf("%6d keys  %6d pages %3f builds/page %6d builds/s  %6d pages/s  %5d avg keys/page  sort every "
-				       "%d deltas  rebuild every %5d bytes  %7d keys/s %8d keybytes/s\n",
-				       (int)keys_generated.size(),
-				       pageCount,
-				       (double)builds / pageCount,
-				       int(builds / elapsed),
-				       int(pageCount / elapsed),
-				       g,
-				       k,
-				       r,
-				       int(keys_generated.size() / elapsed),
-				       int(keybytes / elapsed));
-
-				for (auto p : pages) {
-					delete p;
-				}
-			}
-		}
-	}
-}
-
-int main() {
-	printf("CompactMap test\n");
-
-#ifndef NDEBUG
-	printf("Compiler optimization is OFF\n");
-#endif
-
-	printf("Key prefix compression is %s\n", CompactPreOrderTree::Node::ENABLE_PREFIX ? "ON" : "OFF");
-	printf("Right subtree prefetch is %s\n", CompactPreOrderTree::ENABLE_PREFETCH_RIGHT ? "ON" : "OFF");
-	printf("Left pointer is %s\n", CompactPreOrderTree::Node::ENABLE_LEFT_PTR ? "ON" : "OFF");
-	printf("Fancy build is %s\n", CompactPreOrderTree::ENABLE_FANCY_BUILD ? "ON" : "OFF");
-
-	setThreadLocalDeterministicRandomSeed(1);
-
-	// ingestBenchmark();
-
-	/*for (int subtree_size = 1; subtree_size < 20; subtree_size++) {
-	    printf("Subtree of size %d:\n", subtree_size);
-
-	    int s = lessOrEqualPowerOfTwo((subtree_size - 1) / 2 + 1) - 1;
-
-	    printf("  s=%d\n", s);
-	    printf("  1 + s + s=%d\n", 1 + s + s);
-	    printf("  left: %d\n", subtree_size - 1 - 2 * s);
-
-	    printf("  s*2+1: %d %d\n", s * 2 + 1, subtree_size - (s * 2 + 1) - 1);
-	    printf("  n-s-1: %d %d\n", subtree_size-s-1, s);
-	    printf("  min:   %d %d\n", std::min(s * 2 + 1, subtree_size - s - 1), subtree_size - std::min(s * 2 + 1,
-	subtree_size - s - 1) - 1);
-	}*/
-
-	printf("\n16 byte hexadecimal random keys\n");
-	std::vector<std::string> testData;
-	for (int i = 0; i < 200; i++) {
-		testData.push_back(deterministicRandom()->randomUniqueID().shortString());
-	}
-	std::vector<std::string> sampleQueries;
-	for (int i = 0; i < 10000; i++) {
-		sampleQueries.push_back(
-		    deterministicRandom()->randomUniqueID().shortString().substr(0, deterministicRandom()->randomInt(0, 16)));
-	}
-	compactMapTests(testData, sampleQueries);
-
-	printf("\nRaw index keys\n");
-	testData.clear();
-	sampleQueries.clear();
-	for (int i = 0; i < 100; i++) {
-		testData.push_back(format("%d Main Street #%d, New York NY 12345, United States of America|",
-		                          1234 * (i / 100),
-		                          (i / 10) % 10 + 1000) +
-		                   deterministicRandom()->randomUniqueID().shortString());
-	}
-	for (int i = 0; i < 10000; i++)
-		sampleQueries.push_back(format("%d Main Street", deterministicRandom()->randomInt(1000, 10000)));
-	compactMapTests(testData, sampleQueries, "graph_addresses.dot");
-
-	printf("\nb+tree separators for index keys\n");
-	testData.clear();
-	for (int i = 0; i < 100000; i++) {
-		testData.push_back(format("%d Main Street #%d, New York NY 12345, United States of America|",
-		                          12 * (i / 100),
-		                          (i / 10) % 10 + 1000) +
-		                   deterministicRandom()->randomUniqueID().shortString());
-	}
-	testData = sampleBPlusTreeSeparators(testData, 0);
-	compactMapTests(testData, sampleQueries);
-
-	printf("\nraw document keys\n");
-	testData = sampleDocuments(20);
-	sampleQueries.clear();
-	std::string p = "pre";
-	for (int i = 0; i < 10000; i++)
-		sampleQueries.push_back(
-		    p + BinaryWriter::toValue(deterministicRandom()->randomUniqueID(), Unversioned()).substr(12).toString());
-	compactMapTests(testData, sampleQueries);
-
-	printf("\nb+tree split keys for documents\n");
-	testData = sampleBPlusTreeSeparators(sampleDocuments(30000), p.size());
-	compactMapTests(testData, sampleQueries);
-
-	return 0;
-}
diff --git a/fdbserver/VFSAsync.cpp b/fdbserver/VFSAsync.cpp
index b6a655a010..9ea9007203 100644
--- a/fdbserver/VFSAsync.cpp
+++ b/fdbserver/VFSAsync.cpp
@@ -18,7 +18,7 @@
  * limitations under the License.
  */
 
-#include "sqlite/sqlite3.h"
+#include "sqlite3.h"
 #include <stdio.h>
 #include <string>
 #include <vector>
diff --git a/fdbserver/CoroFlow.actor.cpp b/fdbserver/coroimpl/CoroFlow.actor.cpp
similarity index 100%
rename from fdbserver/CoroFlow.actor.cpp
rename to fdbserver/coroimpl/CoroFlow.actor.cpp
diff --git a/fdbserver/CoroFlowCoro.actor.cpp b/fdbserver/coroimpl/CoroFlowCoro.actor.cpp
similarity index 100%
rename from fdbserver/CoroFlowCoro.actor.cpp
rename to fdbserver/coroimpl/CoroFlowCoro.actor.cpp
diff --git a/fdbserver/ApplyMetadataMutation.h b/fdbserver/include/fdbserver/ApplyMetadataMutation.h
similarity index 100%
rename from fdbserver/ApplyMetadataMutation.h
rename to fdbserver/include/fdbserver/ApplyMetadataMutation.h
diff --git a/fdbserver/ArtMutationBuffer.h b/fdbserver/include/fdbserver/ArtMutationBuffer.h
similarity index 100%
rename from fdbserver/ArtMutationBuffer.h
rename to fdbserver/include/fdbserver/ArtMutationBuffer.h
diff --git a/fdbserver/BackupInterface.h b/fdbserver/include/fdbserver/BackupInterface.h
similarity index 100%
rename from fdbserver/BackupInterface.h
rename to fdbserver/include/fdbserver/BackupInterface.h
diff --git a/fdbserver/BackupProgress.actor.h b/fdbserver/include/fdbserver/BackupProgress.actor.h
similarity index 100%
rename from fdbserver/BackupProgress.actor.h
rename to fdbserver/include/fdbserver/BackupProgress.actor.h
diff --git a/fdbserver/BlobGranuleServerCommon.actor.h b/fdbserver/include/fdbserver/BlobGranuleServerCommon.actor.h
similarity index 100%
rename from fdbserver/BlobGranuleServerCommon.actor.h
rename to fdbserver/include/fdbserver/BlobGranuleServerCommon.actor.h
diff --git a/fdbserver/BlobGranuleValidation.actor.h b/fdbserver/include/fdbserver/BlobGranuleValidation.actor.h
similarity index 100%
rename from fdbserver/BlobGranuleValidation.actor.h
rename to fdbserver/include/fdbserver/BlobGranuleValidation.actor.h
diff --git a/fdbserver/BlobManagerInterface.h b/fdbserver/include/fdbserver/BlobManagerInterface.h
similarity index 100%
rename from fdbserver/BlobManagerInterface.h
rename to fdbserver/include/fdbserver/BlobManagerInterface.h
diff --git a/fdbserver/ClusterController.actor.h b/fdbserver/include/fdbserver/ClusterController.actor.h
similarity index 100%
rename from fdbserver/ClusterController.actor.h
rename to fdbserver/include/fdbserver/ClusterController.actor.h
diff --git a/fdbserver/ClusterRecovery.actor.h b/fdbserver/include/fdbserver/ClusterRecovery.actor.h
similarity index 100%
rename from fdbserver/ClusterRecovery.actor.h
rename to fdbserver/include/fdbserver/ClusterRecovery.actor.h
diff --git a/fdbserver/ConfigBroadcastInterface.h b/fdbserver/include/fdbserver/ConfigBroadcastInterface.h
similarity index 100%
rename from fdbserver/ConfigBroadcastInterface.h
rename to fdbserver/include/fdbserver/ConfigBroadcastInterface.h
diff --git a/fdbserver/ConfigBroadcaster.h b/fdbserver/include/fdbserver/ConfigBroadcaster.h
similarity index 100%
rename from fdbserver/ConfigBroadcaster.h
rename to fdbserver/include/fdbserver/ConfigBroadcaster.h
diff --git a/fdbserver/ConfigFollowerInterface.h b/fdbserver/include/fdbserver/ConfigFollowerInterface.h
similarity index 100%
rename from fdbserver/ConfigFollowerInterface.h
rename to fdbserver/include/fdbserver/ConfigFollowerInterface.h
diff --git a/fdbserver/ConfigNode.h b/fdbserver/include/fdbserver/ConfigNode.h
similarity index 100%
rename from fdbserver/ConfigNode.h
rename to fdbserver/include/fdbserver/ConfigNode.h
diff --git a/fdbserver/ConflictSet.h b/fdbserver/include/fdbserver/ConflictSet.h
similarity index 100%
rename from fdbserver/ConflictSet.h
rename to fdbserver/include/fdbserver/ConflictSet.h
diff --git a/fdbserver/CoordinatedState.h b/fdbserver/include/fdbserver/CoordinatedState.h
similarity index 100%
rename from fdbserver/CoordinatedState.h
rename to fdbserver/include/fdbserver/CoordinatedState.h
diff --git a/fdbserver/CoordinationInterface.h b/fdbserver/include/fdbserver/CoordinationInterface.h
similarity index 100%
rename from fdbserver/CoordinationInterface.h
rename to fdbserver/include/fdbserver/CoordinationInterface.h
diff --git a/fdbserver/CoroFlow.h b/fdbserver/include/fdbserver/CoroFlow.h
similarity index 100%
rename from fdbserver/CoroFlow.h
rename to fdbserver/include/fdbserver/CoroFlow.h
diff --git a/fdbserver/DBCoreState.h b/fdbserver/include/fdbserver/DBCoreState.h
similarity index 100%
rename from fdbserver/DBCoreState.h
rename to fdbserver/include/fdbserver/DBCoreState.h
diff --git a/fdbserver/DDTeamCollection.h b/fdbserver/include/fdbserver/DDTeamCollection.h
similarity index 100%
rename from fdbserver/DDTeamCollection.h
rename to fdbserver/include/fdbserver/DDTeamCollection.h
diff --git a/fdbserver/DDTxnProcessor.h b/fdbserver/include/fdbserver/DDTxnProcessor.h
similarity index 100%
rename from fdbserver/DDTxnProcessor.h
rename to fdbserver/include/fdbserver/DDTxnProcessor.h
diff --git a/fdbserver/DataDistribution.actor.h b/fdbserver/include/fdbserver/DataDistribution.actor.h
similarity index 100%
rename from fdbserver/DataDistribution.actor.h
rename to fdbserver/include/fdbserver/DataDistribution.actor.h
diff --git a/fdbserver/DataDistributorInterface.h b/fdbserver/include/fdbserver/DataDistributorInterface.h
similarity index 100%
rename from fdbserver/DataDistributorInterface.h
rename to fdbserver/include/fdbserver/DataDistributorInterface.h
diff --git a/fdbserver/DeltaTree.h b/fdbserver/include/fdbserver/DeltaTree.h
similarity index 100%
rename from fdbserver/DeltaTree.h
rename to fdbserver/include/fdbserver/DeltaTree.h
diff --git a/fdbserver/EncryptKeyProxyInterface.h b/fdbserver/include/fdbserver/EncryptKeyProxyInterface.h
similarity index 100%
rename from fdbserver/EncryptKeyProxyInterface.h
rename to fdbserver/include/fdbserver/EncryptKeyProxyInterface.h
diff --git a/fdbserver/FDBExecHelper.actor.h b/fdbserver/include/fdbserver/FDBExecHelper.actor.h
similarity index 100%
rename from fdbserver/FDBExecHelper.actor.h
rename to fdbserver/include/fdbserver/FDBExecHelper.actor.h
diff --git a/fdbserver/GetEncryptCipherKeys.h b/fdbserver/include/fdbserver/GetEncryptCipherKeys.h
similarity index 100%
rename from fdbserver/GetEncryptCipherKeys.h
rename to fdbserver/include/fdbserver/GetEncryptCipherKeys.h
diff --git a/fdbserver/IConfigConsumer.h b/fdbserver/include/fdbserver/IConfigConsumer.h
similarity index 100%
rename from fdbserver/IConfigConsumer.h
rename to fdbserver/include/fdbserver/IConfigConsumer.h
diff --git a/fdbserver/IDiskQueue.h b/fdbserver/include/fdbserver/IDiskQueue.h
similarity index 100%
rename from fdbserver/IDiskQueue.h
rename to fdbserver/include/fdbserver/IDiskQueue.h
diff --git a/fdbserver/IKeyValueContainer.h b/fdbserver/include/fdbserver/IKeyValueContainer.h
similarity index 100%
rename from fdbserver/IKeyValueContainer.h
rename to fdbserver/include/fdbserver/IKeyValueContainer.h
diff --git a/fdbserver/IKeyValueStore.h b/fdbserver/include/fdbserver/IKeyValueStore.h
similarity index 100%
rename from fdbserver/IKeyValueStore.h
rename to fdbserver/include/fdbserver/IKeyValueStore.h
diff --git a/fdbserver/IPager.h b/fdbserver/include/fdbserver/IPager.h
similarity index 100%
rename from fdbserver/IPager.h
rename to fdbserver/include/fdbserver/IPager.h
diff --git a/fdbserver/KmsConnector.h b/fdbserver/include/fdbserver/KmsConnector.h
similarity index 100%
rename from fdbserver/KmsConnector.h
rename to fdbserver/include/fdbserver/KmsConnector.h
diff --git a/fdbserver/KmsConnectorInterface.h b/fdbserver/include/fdbserver/KmsConnectorInterface.h
similarity index 100%
rename from fdbserver/KmsConnectorInterface.h
rename to fdbserver/include/fdbserver/KmsConnectorInterface.h
diff --git a/fdbserver/KnobProtectiveGroups.h b/fdbserver/include/fdbserver/KnobProtectiveGroups.h
similarity index 100%
rename from fdbserver/KnobProtectiveGroups.h
rename to fdbserver/include/fdbserver/KnobProtectiveGroups.h
diff --git a/fdbserver/Knobs.h b/fdbserver/include/fdbserver/Knobs.h
similarity index 100%
rename from fdbserver/Knobs.h
rename to fdbserver/include/fdbserver/Knobs.h
diff --git a/fdbserver/LatencyBandConfig.h b/fdbserver/include/fdbserver/LatencyBandConfig.h
similarity index 100%
rename from fdbserver/LatencyBandConfig.h
rename to fdbserver/include/fdbserver/LatencyBandConfig.h
diff --git a/fdbserver/LeaderElection.h b/fdbserver/include/fdbserver/LeaderElection.h
similarity index 100%
rename from fdbserver/LeaderElection.h
rename to fdbserver/include/fdbserver/LeaderElection.h
diff --git a/fdbserver/LocalConfiguration.h b/fdbserver/include/fdbserver/LocalConfiguration.h
similarity index 100%
rename from fdbserver/LocalConfiguration.h
rename to fdbserver/include/fdbserver/LocalConfiguration.h
diff --git a/fdbserver/LogProtocolMessage.h b/fdbserver/include/fdbserver/LogProtocolMessage.h
similarity index 100%
rename from fdbserver/LogProtocolMessage.h
rename to fdbserver/include/fdbserver/LogProtocolMessage.h
diff --git a/fdbserver/LogSystem.h b/fdbserver/include/fdbserver/LogSystem.h
similarity index 100%
rename from fdbserver/LogSystem.h
rename to fdbserver/include/fdbserver/LogSystem.h
diff --git a/fdbserver/LogSystemConfig.h b/fdbserver/include/fdbserver/LogSystemConfig.h
similarity index 100%
rename from fdbserver/LogSystemConfig.h
rename to fdbserver/include/fdbserver/LogSystemConfig.h
diff --git a/fdbserver/LogSystemDiskQueueAdapter.h b/fdbserver/include/fdbserver/LogSystemDiskQueueAdapter.h
similarity index 100%
rename from fdbserver/LogSystemDiskQueueAdapter.h
rename to fdbserver/include/fdbserver/LogSystemDiskQueueAdapter.h
diff --git a/fdbserver/MasterInterface.h b/fdbserver/include/fdbserver/MasterInterface.h
similarity index 100%
rename from fdbserver/MasterInterface.h
rename to fdbserver/include/fdbserver/MasterInterface.h
diff --git a/fdbserver/MetricLogger.actor.h b/fdbserver/include/fdbserver/MetricLogger.actor.h
similarity index 100%
rename from fdbserver/MetricLogger.actor.h
rename to fdbserver/include/fdbserver/MetricLogger.actor.h
diff --git a/fdbserver/MoveKeys.actor.h b/fdbserver/include/fdbserver/MoveKeys.actor.h
similarity index 100%
rename from fdbserver/MoveKeys.actor.h
rename to fdbserver/include/fdbserver/MoveKeys.actor.h
diff --git a/fdbserver/MutationTracking.h b/fdbserver/include/fdbserver/MutationTracking.h
similarity index 100%
rename from fdbserver/MutationTracking.h
rename to fdbserver/include/fdbserver/MutationTracking.h
diff --git a/fdbserver/NetworkTest.h b/fdbserver/include/fdbserver/NetworkTest.h
similarity index 100%
rename from fdbserver/NetworkTest.h
rename to fdbserver/include/fdbserver/NetworkTest.h
diff --git a/fdbserver/OTELSpanContextMessage.h b/fdbserver/include/fdbserver/OTELSpanContextMessage.h
similarity index 100%
rename from fdbserver/OTELSpanContextMessage.h
rename to fdbserver/include/fdbserver/OTELSpanContextMessage.h
diff --git a/fdbserver/OnDemandStore.h b/fdbserver/include/fdbserver/OnDemandStore.h
similarity index 100%
rename from fdbserver/OnDemandStore.h
rename to fdbserver/include/fdbserver/OnDemandStore.h
diff --git a/fdbserver/PaxosConfigConsumer.h b/fdbserver/include/fdbserver/PaxosConfigConsumer.h
similarity index 100%
rename from fdbserver/PaxosConfigConsumer.h
rename to fdbserver/include/fdbserver/PaxosConfigConsumer.h
diff --git a/fdbserver/ProxyCommitData.actor.h b/fdbserver/include/fdbserver/ProxyCommitData.actor.h
similarity index 100%
rename from fdbserver/ProxyCommitData.actor.h
rename to fdbserver/include/fdbserver/ProxyCommitData.actor.h
diff --git a/fdbserver/QuietDatabase.h b/fdbserver/include/fdbserver/QuietDatabase.h
similarity index 100%
rename from fdbserver/QuietDatabase.h
rename to fdbserver/include/fdbserver/QuietDatabase.h
diff --git a/fdbserver/RESTKmsConnector.h b/fdbserver/include/fdbserver/RESTKmsConnector.h
similarity index 100%
rename from fdbserver/RESTKmsConnector.h
rename to fdbserver/include/fdbserver/RESTKmsConnector.h
diff --git a/fdbserver/RadixTree.h b/fdbserver/include/fdbserver/RadixTree.h
similarity index 100%
rename from fdbserver/RadixTree.h
rename to fdbserver/include/fdbserver/RadixTree.h
diff --git a/fdbserver/Ratekeeper.h b/fdbserver/include/fdbserver/Ratekeeper.h
similarity index 100%
rename from fdbserver/Ratekeeper.h
rename to fdbserver/include/fdbserver/Ratekeeper.h
diff --git a/fdbserver/RatekeeperInterface.h b/fdbserver/include/fdbserver/RatekeeperInterface.h
similarity index 100%
rename from fdbserver/RatekeeperInterface.h
rename to fdbserver/include/fdbserver/RatekeeperInterface.h
diff --git a/fdbserver/RecoveryState.h b/fdbserver/include/fdbserver/RecoveryState.h
similarity index 100%
rename from fdbserver/RecoveryState.h
rename to fdbserver/include/fdbserver/RecoveryState.h
diff --git a/fdbserver/RemoteIKeyValueStore.actor.h b/fdbserver/include/fdbserver/RemoteIKeyValueStore.actor.h
similarity index 100%
rename from fdbserver/RemoteIKeyValueStore.actor.h
rename to fdbserver/include/fdbserver/RemoteIKeyValueStore.actor.h
diff --git a/fdbserver/ResolutionBalancer.actor.h b/fdbserver/include/fdbserver/ResolutionBalancer.actor.h
similarity index 100%
rename from fdbserver/ResolutionBalancer.actor.h
rename to fdbserver/include/fdbserver/ResolutionBalancer.actor.h
diff --git a/fdbserver/ResolverInterface.h b/fdbserver/include/fdbserver/ResolverInterface.h
similarity index 100%
rename from fdbserver/ResolverInterface.h
rename to fdbserver/include/fdbserver/ResolverInterface.h
diff --git a/fdbserver/RestoreApplier.actor.h b/fdbserver/include/fdbserver/RestoreApplier.actor.h
similarity index 100%
rename from fdbserver/RestoreApplier.actor.h
rename to fdbserver/include/fdbserver/RestoreApplier.actor.h
diff --git a/fdbserver/RestoreCommon.actor.h b/fdbserver/include/fdbserver/RestoreCommon.actor.h
similarity index 100%
rename from fdbserver/RestoreCommon.actor.h
rename to fdbserver/include/fdbserver/RestoreCommon.actor.h
diff --git a/fdbserver/RestoreController.actor.h b/fdbserver/include/fdbserver/RestoreController.actor.h
similarity index 100%
rename from fdbserver/RestoreController.actor.h
rename to fdbserver/include/fdbserver/RestoreController.actor.h
diff --git a/fdbserver/RestoreLoader.actor.h b/fdbserver/include/fdbserver/RestoreLoader.actor.h
similarity index 100%
rename from fdbserver/RestoreLoader.actor.h
rename to fdbserver/include/fdbserver/RestoreLoader.actor.h
diff --git a/fdbserver/RestoreRoleCommon.actor.h b/fdbserver/include/fdbserver/RestoreRoleCommon.actor.h
similarity index 100%
rename from fdbserver/RestoreRoleCommon.actor.h
rename to fdbserver/include/fdbserver/RestoreRoleCommon.actor.h
diff --git a/fdbserver/RestoreUtil.h b/fdbserver/include/fdbserver/RestoreUtil.h
similarity index 100%
rename from fdbserver/RestoreUtil.h
rename to fdbserver/include/fdbserver/RestoreUtil.h
diff --git a/fdbserver/RestoreWorker.actor.h b/fdbserver/include/fdbserver/RestoreWorker.actor.h
similarity index 100%
rename from fdbserver/RestoreWorker.actor.h
rename to fdbserver/include/fdbserver/RestoreWorker.actor.h
diff --git a/fdbserver/RestoreWorkerInterface.actor.h b/fdbserver/include/fdbserver/RestoreWorkerInterface.actor.h
similarity index 100%
rename from fdbserver/RestoreWorkerInterface.actor.h
rename to fdbserver/include/fdbserver/RestoreWorkerInterface.actor.h
diff --git a/fdbserver/RkTagThrottleCollection.h b/fdbserver/include/fdbserver/RkTagThrottleCollection.h
similarity index 100%
rename from fdbserver/RkTagThrottleCollection.h
rename to fdbserver/include/fdbserver/RkTagThrottleCollection.h
diff --git a/fdbserver/RocksDBCheckpointUtils.actor.h b/fdbserver/include/fdbserver/RocksDBCheckpointUtils.actor.h
similarity index 100%
rename from fdbserver/RocksDBCheckpointUtils.actor.h
rename to fdbserver/include/fdbserver/RocksDBCheckpointUtils.actor.h
diff --git a/fdbserver/RoleLineage.actor.h b/fdbserver/include/fdbserver/RoleLineage.actor.h
similarity index 100%
rename from fdbserver/RoleLineage.actor.h
rename to fdbserver/include/fdbserver/RoleLineage.actor.h
diff --git a/fdbserver/ServerCheckpoint.actor.h b/fdbserver/include/fdbserver/ServerCheckpoint.actor.h
similarity index 100%
rename from fdbserver/ServerCheckpoint.actor.h
rename to fdbserver/include/fdbserver/ServerCheckpoint.actor.h
diff --git a/fdbserver/ServerDBInfo.actor.h b/fdbserver/include/fdbserver/ServerDBInfo.actor.h
similarity index 100%
rename from fdbserver/ServerDBInfo.actor.h
rename to fdbserver/include/fdbserver/ServerDBInfo.actor.h
diff --git a/fdbserver/ServerDBInfo.h b/fdbserver/include/fdbserver/ServerDBInfo.h
similarity index 100%
rename from fdbserver/ServerDBInfo.h
rename to fdbserver/include/fdbserver/ServerDBInfo.h
diff --git a/fdbserver/SimEncryptKmsProxy.actor.h b/fdbserver/include/fdbserver/SimEncryptKmsProxy.actor.h
similarity index 100%
rename from fdbserver/SimEncryptKmsProxy.actor.h
rename to fdbserver/include/fdbserver/SimEncryptKmsProxy.actor.h
diff --git a/fdbserver/SimKmsConnector.h b/fdbserver/include/fdbserver/SimKmsConnector.h
similarity index 100%
rename from fdbserver/SimKmsConnector.h
rename to fdbserver/include/fdbserver/SimKmsConnector.h
diff --git a/fdbserver/SimpleConfigConsumer.h b/fdbserver/include/fdbserver/SimpleConfigConsumer.h
similarity index 100%
rename from fdbserver/SimpleConfigConsumer.h
rename to fdbserver/include/fdbserver/SimpleConfigConsumer.h
diff --git a/fdbserver/SimulatedCluster.h b/fdbserver/include/fdbserver/SimulatedCluster.h
similarity index 100%
rename from fdbserver/SimulatedCluster.h
rename to fdbserver/include/fdbserver/SimulatedCluster.h
diff --git a/fdbserver/SpanContextMessage.h b/fdbserver/include/fdbserver/SpanContextMessage.h
similarity index 100%
rename from fdbserver/SpanContextMessage.h
rename to fdbserver/include/fdbserver/SpanContextMessage.h
diff --git a/fdbserver/Status.h b/fdbserver/include/fdbserver/Status.h
similarity index 100%
rename from fdbserver/Status.h
rename to fdbserver/include/fdbserver/Status.h
diff --git a/fdbserver/StorageMetrics.h b/fdbserver/include/fdbserver/StorageMetrics.h
similarity index 100%
rename from fdbserver/StorageMetrics.h
rename to fdbserver/include/fdbserver/StorageMetrics.h
diff --git a/fdbserver/TCInfo.h b/fdbserver/include/fdbserver/TCInfo.h
similarity index 100%
rename from fdbserver/TCInfo.h
rename to fdbserver/include/fdbserver/TCInfo.h
diff --git a/fdbserver/TLogInterface.h b/fdbserver/include/fdbserver/TLogInterface.h
similarity index 100%
rename from fdbserver/TLogInterface.h
rename to fdbserver/include/fdbserver/TLogInterface.h
diff --git a/fdbserver/TSSMappingUtil.actor.h b/fdbserver/include/fdbserver/TSSMappingUtil.actor.h
similarity index 100%
rename from fdbserver/TSSMappingUtil.actor.h
rename to fdbserver/include/fdbserver/TSSMappingUtil.actor.h
diff --git a/fdbserver/TagPartitionedLogSystem.actor.h b/fdbserver/include/fdbserver/TagPartitionedLogSystem.actor.h
similarity index 100%
rename from fdbserver/TagPartitionedLogSystem.actor.h
rename to fdbserver/include/fdbserver/TagPartitionedLogSystem.actor.h
diff --git a/fdbserver/TagThrottler.h b/fdbserver/include/fdbserver/TagThrottler.h
similarity index 100%
rename from fdbserver/TagThrottler.h
rename to fdbserver/include/fdbserver/TagThrottler.h
diff --git a/fdbserver/TenantCache.h b/fdbserver/include/fdbserver/TenantCache.h
similarity index 100%
rename from fdbserver/TenantCache.h
rename to fdbserver/include/fdbserver/TenantCache.h
diff --git a/fdbserver/TesterInterface.actor.h b/fdbserver/include/fdbserver/TesterInterface.actor.h
similarity index 100%
rename from fdbserver/TesterInterface.actor.h
rename to fdbserver/include/fdbserver/TesterInterface.actor.h
diff --git a/fdbserver/TransactionTagCounter.h b/fdbserver/include/fdbserver/TransactionTagCounter.h
similarity index 100%
rename from fdbserver/TransactionTagCounter.h
rename to fdbserver/include/fdbserver/TransactionTagCounter.h
diff --git a/fdbserver/VFSAsync.h b/fdbserver/include/fdbserver/VFSAsync.h
similarity index 100%
rename from fdbserver/VFSAsync.h
rename to fdbserver/include/fdbserver/VFSAsync.h
diff --git a/fdbserver/WaitFailure.h b/fdbserver/include/fdbserver/WaitFailure.h
similarity index 100%
rename from fdbserver/WaitFailure.h
rename to fdbserver/include/fdbserver/WaitFailure.h
diff --git a/fdbserver/WorkerInterface.actor.h b/fdbserver/include/fdbserver/WorkerInterface.actor.h
similarity index 100%
rename from fdbserver/WorkerInterface.actor.h
rename to fdbserver/include/fdbserver/WorkerInterface.actor.h
diff --git a/fdbserver/art.h b/fdbserver/include/fdbserver/art.h
similarity index 100%
rename from fdbserver/art.h
rename to fdbserver/include/fdbserver/art.h
diff --git a/fdbserver/art_impl.h b/fdbserver/include/fdbserver/art_impl.h
similarity index 100%
rename from fdbserver/art_impl.h
rename to fdbserver/include/fdbserver/art_impl.h
diff --git a/fdbserver/pubsub.h b/fdbserver/include/fdbserver/pubsub.h
similarity index 100%
rename from fdbserver/pubsub.h
rename to fdbserver/include/fdbserver/pubsub.h
diff --git a/fdbserver/template_fdb.h b/fdbserver/include/fdbserver/template_fdb.h
similarity index 100%
rename from fdbserver/template_fdb.h
rename to fdbserver/include/fdbserver/template_fdb.h
diff --git a/fdbserver/workloads/ApiWorkload.h b/fdbserver/include/fdbserver/workloads/ApiWorkload.h
similarity index 100%
rename from fdbserver/workloads/ApiWorkload.h
rename to fdbserver/include/fdbserver/workloads/ApiWorkload.h
diff --git a/fdbserver/workloads/AsyncFile.actor.h b/fdbserver/include/fdbserver/workloads/AsyncFile.actor.h
similarity index 100%
rename from fdbserver/workloads/AsyncFile.actor.h
rename to fdbserver/include/fdbserver/workloads/AsyncFile.actor.h
diff --git a/fdbserver/workloads/BlobStoreWorkload.h b/fdbserver/include/fdbserver/workloads/BlobStoreWorkload.h
similarity index 100%
rename from fdbserver/workloads/BlobStoreWorkload.h
rename to fdbserver/include/fdbserver/workloads/BlobStoreWorkload.h
diff --git a/fdbserver/workloads/BulkSetup.actor.h b/fdbserver/include/fdbserver/workloads/BulkSetup.actor.h
similarity index 100%
rename from fdbserver/workloads/BulkSetup.actor.h
rename to fdbserver/include/fdbserver/workloads/BulkSetup.actor.h
diff --git a/fdbserver/workloads/MemoryKeyValueStore.h b/fdbserver/include/fdbserver/workloads/MemoryKeyValueStore.h
similarity index 100%
rename from fdbserver/workloads/MemoryKeyValueStore.h
rename to fdbserver/include/fdbserver/workloads/MemoryKeyValueStore.h
diff --git a/fdbserver/workloads/ReadWriteWorkload.actor.h b/fdbserver/include/fdbserver/workloads/ReadWriteWorkload.actor.h
similarity index 100%
rename from fdbserver/workloads/ReadWriteWorkload.actor.h
rename to fdbserver/include/fdbserver/workloads/ReadWriteWorkload.actor.h
diff --git a/fdbserver/workloads/TPCCWorkload.h b/fdbserver/include/fdbserver/workloads/TPCCWorkload.h
similarity index 100%
rename from fdbserver/workloads/TPCCWorkload.h
rename to fdbserver/include/fdbserver/workloads/TPCCWorkload.h
diff --git a/fdbserver/workloads/workloads.actor.h b/fdbserver/include/fdbserver/workloads/workloads.actor.h
similarity index 100%
rename from fdbserver/workloads/workloads.actor.h
rename to fdbserver/include/fdbserver/workloads/workloads.actor.h