diff --git a/src/main/java/io/akarin/server/misc/CopyOnWriteHashMap.java b/src/main/java/io/akarin/server/misc/CopyOnWriteHashMap.java
new file mode 100644
index 000000000..ca9c60ea7
--- /dev/null
+++ b/src/main/java/io/akarin/server/misc/CopyOnWriteHashMap.java
@@ -0,0 +1,184 @@
+package io.akarin.server.misc;
+
+import java.io.Serializable;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.atomic.AtomicReference;
+
+/**
+ * A thread-safe version of {@link Map} in which all operations that change the
+ * Map are implemented by making a new copy of the underlying Map.
+ *
+ * While the creation of a new Map can be expensive, this class is designed for
+ * cases in which the primary function is to read data from the Map, not to
+ * modify the Map. Therefore the operations that do not cause a change to this
+ * class happen quickly and concurrently.
+ *
+ * @author Kuzma Deretuke
+ */
+public class CopyOnWriteHashMap implements Map, Serializable, Cloneable {
+ private static final long serialVersionUID = 5481095911554321115L;
+ private AtomicReference