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 { }