diff --git a/src/main/java/betterquesting/api2/storage/SequentialDataBase.java b/src/main/java/betterquesting/api2/storage/SequentialDataBase.java
new file mode 100644
index 000000000..5d6811355
--- /dev/null
+++ b/src/main/java/betterquesting/api2/storage/SequentialDataBase.java
@@ -0,0 +1,52 @@
+package betterquesting.api2.storage;
+
+import java.util.BitSet;
+
+/**
+ * a database implementation specialized for ids that're sequential, dense and not randomly generated
+ *
+ * see {@link RandomIndexDatabase} for database specialized in handling randomly generated ids
+ */
+public class SequentialDataBase extends AbstractDatabase {
+
+ private final BitSet ids = new BitSet();
+ /**
+ * the "smallest acceptable" id, any id smaller than this is considered as used and can
+ * be skipped when searching for new id, this condition can be maintained by:
+ * - refresh lowerBound after new id is generated: {@link #nextID()}
+ * - refresh lowerBound after one id is removed: {@link #removeID(int)}
+ */
+ private int lowerBound = 0;
+
+ @Override
+ public synchronized int nextID() {
+ int next = ids.nextClearBit(lowerBound);
+ lowerBound = next + 1;
+ return next;
+ }
+
+ @Override
+ public synchronized DBEntry add(int id, T value) {
+ DBEntry result = super.add(id, value);
+ // Don't add when an exception is thrown
+ ids.set(id);
+ // lowerBound = id; //no, lowerBound will not be refreshed here, delay to next `nextID()` call instead
+ return result;
+ }
+
+ @Override
+ public synchronized boolean removeID(int key) {
+ boolean result = super.removeID(key);
+ if (result) {
+ ids.clear(key);
+ lowerBound = Math.min(key, lowerBound);
+ }
+ return result;
+ }
+
+ @Override
+ public synchronized void reset() {
+ super.reset();
+ ids.clear();
+ }
+}
diff --git a/src/main/java/betterquesting/api2/storage/SimpleDatabase.java b/src/main/java/betterquesting/api2/storage/SimpleDatabase.java
index 1de0070ed..a16b3aac2 100644
--- a/src/main/java/betterquesting/api2/storage/SimpleDatabase.java
+++ b/src/main/java/betterquesting/api2/storage/SimpleDatabase.java
@@ -1,38 +1,8 @@
package betterquesting.api2.storage;
-import java.util.BitSet;
-import java.util.Collections;
-import java.util.List;
-import java.util.TreeMap;
-
-public class SimpleDatabase extends AbstractDatabase {
-
- private final BitSet idMap = new BitSet();
-
- @Override
- public synchronized int nextID() {
- return idMap.nextClearBit(0);
- }
-
- @Override
- public synchronized DBEntry add(int id, T value) {
- DBEntry result = super.add(id, value);
- // Don't add when an exception is thrown
- idMap.set(id);
- return result;
- }
-
- @Override
- public synchronized boolean removeID(int key) {
- boolean result = super.removeID(key);
- if (result) idMap.clear(key);
- return result;
- }
-
- @Override
- public synchronized void reset() {
- super.reset();
- idMap.clear();
- }
+/**
+ * @see SequentialDataBase
+ */
+public class SimpleDatabase extends SequentialDataBase {
}