You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@baremaps.apache.org by bc...@apache.org on 2025/04/05 12:44:34 UTC
(incubator-baremaps) branch main updated: Data collection refactoring (#955)
This is an automated email from the ASF dual-hosted git repository.
bchapuis pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/incubator-baremaps.git
The following commit(s) were added to refs/heads/main by this push:
new dc8ff321e Data collection refactoring (#955)
dc8ff321e is described below
commit dc8ff321e9419222e4e0239681bddb1c42f62615
Author: Bertil Chapuis <bc...@gmail.com>
AuthorDate: Sat Apr 5 14:44:30 2025 +0200
Data collection refactoring (#955)
* Improve resource management
* Persist size to memory in AppendOnlyLog
* Make DataCollection extend AutoCloseable
* Make DataMap extend AutoCloseable
* Add DirectHashDataMap
* Add builders to all data collections
* Make data collections constructors private
* Use the builders consistently in calling code
* Improve the javadoc and make it more consistent
* Clean unused files
---
.../apache/baremaps/workflow/WorkflowContext.java | 47 +-
.../org/apache/baremaps/calcite/CalciteTest.java | 12 +-
.../baremaps/tasks/ImportUpdateSampleTest.java | 14 +-
.../baremaps/data/collection/AppendOnlyLog.java | 129 +++++-
.../baremaps/data/collection/DataCollection.java | 51 ++-
.../data/collection/DataCollectionException.java | 22 +-
.../data/collection/DataCollectionMapper.java | 16 +-
.../baremaps/data/collection/DataConversions.java | 69 ++-
.../apache/baremaps/data/collection/DataList.java | 21 +-
.../apache/baremaps/data/collection/DataMap.java | 76 ++--
.../data/collection/DirectHashDataMap.java | 496 +++++++++++++++++++++
.../data/collection/FixedSizeDataList.java | 87 +++-
.../baremaps/data/collection/IndexedDataList.java | 82 +++-
.../baremaps/data/collection/IndexedDataMap.java | 79 +++-
.../data/collection/MemoryAlignedDataList.java | 90 +++-
.../data/collection/MemoryAlignedDataMap.java | 83 +++-
.../baremaps/data/collection/MonotonicDataMap.java | 112 +++--
.../data/collection/MonotonicFixedSizeDataMap.java | 99 +++-
.../data/collection/MonotonicPairedDataMap.java | 80 +++-
.../org/apache/baremaps/data/memory/Memory.java | 114 +++--
.../baremaps/data/memory/MemoryException.java | 18 +-
.../data/memory/MemoryMappedDirectory.java | 44 +-
.../baremaps/data/memory/MemoryMappedFile.java | 42 +-
.../apache/baremaps/data/memory/OffHeapMemory.java | 32 +-
.../apache/baremaps/data/memory/OnHeapMemory.java | 31 +-
.../baremaps/data/type/BooleanArrayDataType.java | 4 +-
.../apache/baremaps/data/type/BooleanDataType.java | 8 +-
.../baremaps/data/type/BooleanListDataType.java | 4 +-
.../baremaps/data/type/ByteArrayDataType.java | 2 +-
.../apache/baremaps/data/type/ByteDataType.java | 10 +-
.../baremaps/data/type/ByteListDataType.java | 2 +-
.../data/type/CoordinateArrayDataType.java | 3 +-
.../baremaps/data/type/CoordinateDataType.java | 6 +-
.../org/apache/baremaps/data/type/DataType.java | 24 +-
.../baremaps/data/type/DoubleArrayDataType.java | 6 +-
.../apache/baremaps/data/type/DoubleDataType.java | 10 +-
.../baremaps/data/type/DoubleListDataType.java | 6 +-
.../baremaps/data/type/FixedSizeDataType.java | 8 +-
.../baremaps/data/type/FloatArrayDataType.java | 6 +-
.../apache/baremaps/data/type/FloatDataType.java | 6 +-
.../baremaps/data/type/FloatListDataType.java | 6 +-
.../data/type/GeometryCollectionDataType.java | 11 +-
.../baremaps/data/type/GeometryDataType.java | 8 +-
.../baremaps/data/type/IntegerArrayDataType.java | 7 +-
.../apache/baremaps/data/type/IntegerDataType.java | 6 +-
.../baremaps/data/type/IntegerListDataType.java | 7 +-
.../baremaps/data/type/LineStringDataType.java | 6 +-
.../apache/baremaps/data/type/ListDataType.java | 9 +-
.../apache/baremaps/data/type/LonLatDataType.java | 23 +-
.../baremaps/data/type/LongArrayDataType.java | 6 +-
.../apache/baremaps/data/type/LongDataType.java | 7 +-
.../baremaps/data/type/LongListDataType.java | 6 +-
.../org/apache/baremaps/data/type/MapDataType.java | 16 +
.../baremaps/data/type/MemoryAlignedDataType.java | 7 +-
.../data/type/MultiLineStringDataType.java | 7 +-
.../baremaps/data/type/MultiPointDataType.java | 6 +-
.../baremaps/data/type/MultiPolygonDataType.java | 6 +-
.../baremaps/data/type/NullableDataType.java | 10 +-
.../apache/baremaps/data/type/PairDataType.java | 35 +-
.../apache/baremaps/data/type/PointDataType.java | 6 +-
.../apache/baremaps/data/type/PolygonDataType.java | 6 +-
.../org/apache/baremaps/data/type/RowDataType.java | 14 +-
.../baremaps/data/type/ShortArrayDataType.java | 4 +-
.../apache/baremaps/data/type/ShortDataType.java | 8 +-
.../baremaps/data/type/ShortListDataType.java | 6 +-
.../baremaps/data/type/SmallIntegerDataType.java | 12 +-
.../baremaps/data/type/SmallLongDataType.java | 12 +-
.../apache/baremaps/data/type/StringDataType.java | 2 +-
.../org/apache/baremaps/data/type/WKBDataType.java | 24 +-
.../apache/baremaps/data/AppendOnlyLogTest.java | 15 +-
.../org/apache/baremaps/data/DataListTest.java | 18 +-
.../java/org/apache/baremaps/data/DataMapTest.java | 45 +-
.../apache/baremaps/data/SizedDataListTest.java | 10 +-
.../data/collection/IndexedDataMapTest.java | 6 +-
.../data/collection/MemoryAlignedDataMapTest.java | 5 +-
.../baremaps/data/sort/BinarySearchTest.java | 4 +-
.../baremaps/data/sort/ExternalMergeSortTest.java | 13 +-
77 files changed, 1949 insertions(+), 501 deletions(-)
diff --git a/baremaps-core/src/main/java/org/apache/baremaps/workflow/WorkflowContext.java b/baremaps-core/src/main/java/org/apache/baremaps/workflow/WorkflowContext.java
index bf9c03c10..f940edc3d 100644
--- a/baremaps-core/src/main/java/org/apache/baremaps/workflow/WorkflowContext.java
+++ b/baremaps-core/src/main/java/org/apache/baremaps/workflow/WorkflowContext.java
@@ -73,34 +73,43 @@ public class WorkflowContext {
private <T> DataMap<Long, T> getMemoryAlignedDataMap(String name, FixedSizeDataType<T> dataType)
throws IOException {
- var coordinateDir = Files.createDirectories(cacheDir.resolve(name));
- return new MemoryAlignedDataMap<>(
- dataType,
- new MemoryMappedDirectory(coordinateDir));
+ Path coordinateDir = Files.createDirectories(cacheDir.resolve(name));
+ return MemoryAlignedDataMap.<T>builder()
+ .dataType(dataType)
+ .memory(new MemoryMappedDirectory(coordinateDir))
+ .build();
}
private <T> DataMap<Long, T> getMonotonicDataMap(String name, DataType<T> dataType)
throws IOException {
- var mapDir = Files.createDirectories(cacheDir.resolve(name));
- var keysDir = Files.createDirectories(mapDir.resolve("keys"));
- var valuesDir = Files.createDirectories(mapDir.resolve("values"));
- return new MonotonicDataMap<>(
- new MemoryAlignedDataList<>(
- new PairDataType<>(new LongDataType(), new LongDataType()),
- new MemoryMappedDirectory(keysDir)),
- new AppendOnlyLog<>(
- dataType,
- new MemoryMappedDirectory(valuesDir)));
+ Path mapDir = Files.createDirectories(cacheDir.resolve(name));
+ Path keysDir = Files.createDirectories(mapDir.resolve("keys"));
+ Path valuesDir = Files.createDirectories(mapDir.resolve("values"));
+ MemoryAlignedDataList<PairDataType.Pair<Long, Long>> keys =
+ MemoryAlignedDataList.<PairDataType.Pair<Long, Long>>builder()
+ .dataType(new PairDataType<>(new LongDataType(), new LongDataType()))
+ .memory(new MemoryMappedDirectory(keysDir))
+ .build();
+ AppendOnlyLog<T> values = AppendOnlyLog.<T>builder()
+ .dataType(dataType)
+ .values(new MemoryMappedDirectory(valuesDir))
+ .build();
+ return MonotonicDataMap.<T>builder()
+ .keys(keys)
+ .values(values)
+ .build();
}
private DataMap<Long, Coordinate> getMonotonicPairedDataMap(String name,
DataType<Coordinate> dataType)
throws IOException {
- var mapDir = Files.createDirectories(cacheDir.resolve(name));
- return new MonotonicPairedDataMap<>(
- new MemoryAlignedDataList<>(
- new PairDataType<>(new LongDataType(), new LonLatDataType()),
- new MemoryMappedDirectory(Files.createDirectories(mapDir))));
+ Path mapDir = Files.createDirectories(cacheDir.resolve(name));
+ return MonotonicPairedDataMap.<Coordinate>builder()
+ .values(MemoryAlignedDataList.<PairDataType.Pair<Long, Coordinate>>builder()
+ .dataType(new PairDataType<>(new LongDataType(), new LonLatDataType()))
+ .memory(new MemoryMappedDirectory(Files.createDirectories(mapDir)))
+ .build())
+ .build();
}
public void cleanCache() throws IOException {
diff --git a/baremaps-core/src/test/java/org/apache/baremaps/calcite/CalciteTest.java b/baremaps-core/src/test/java/org/apache/baremaps/calcite/CalciteTest.java
index efc13eb4d..482d15885 100644
--- a/baremaps-core/src/test/java/org/apache/baremaps/calcite/CalciteTest.java
+++ b/baremaps-core/src/test/java/org/apache/baremaps/calcite/CalciteTest.java
@@ -80,7 +80,11 @@ class CalciteTest {
new DataColumnFixed("geometry", Cardinality.OPTIONAL, Type.GEOMETRY)));
DataTable cityDataTable = new BaremapsDataTable(
cityRowType,
- new IndexedDataList<>(new AppendOnlyLog<>(new RowDataType(cityRowType))));
+ IndexedDataList.<DataRow>builder()
+ .values(AppendOnlyLog.<DataRow>builder()
+ .dataType(new RowDataType(cityRowType))
+ .build())
+ .build());
cityDataTable.add(new DataRowImpl(cityDataTable.schema(),
List.of(1, "Paris", geometryFactory.createPoint(new Coordinate(2.3522, 48.8566)))));
cityDataTable.add(new DataRowImpl(cityDataTable.schema(),
@@ -94,7 +98,11 @@ class CalciteTest {
new DataColumnFixed("population", Cardinality.OPTIONAL, Type.INTEGER)));
DataTable populationDataTable = new BaremapsDataTable(
populationRowType,
- new IndexedDataList<>(new AppendOnlyLog<>(new RowDataType(populationRowType))));
+ IndexedDataList.<DataRow>builder()
+ .values(AppendOnlyLog.<DataRow>builder()
+ .dataType(new RowDataType(populationRowType))
+ .build())
+ .build());
populationDataTable
.add(new DataRowImpl(populationDataTable.schema(), List.of(1, 2_161_000)));
populationDataTable
diff --git a/baremaps-core/src/test/java/org/apache/baremaps/tasks/ImportUpdateSampleTest.java b/baremaps-core/src/test/java/org/apache/baremaps/tasks/ImportUpdateSampleTest.java
index 4aa327f47..1926f4059 100644
--- a/baremaps-core/src/test/java/org/apache/baremaps/tasks/ImportUpdateSampleTest.java
+++ b/baremaps-core/src/test/java/org/apache/baremaps/tasks/ImportUpdateSampleTest.java
@@ -55,9 +55,19 @@ class ImportUpdateSampleTest extends PostgresRepositoryTest {
// Initialize the data maps
Map<Long, Coordinate> coordinateMap = DataConversions.asMap(
- new IndexedDataMap<>(new AppendOnlyLog<>(new CoordinateDataType(), new OnHeapMemory())));
+ IndexedDataMap.<Coordinate>builder()
+ .values(AppendOnlyLog.<Coordinate>builder()
+ .dataType(new CoordinateDataType())
+ .memory(new OnHeapMemory())
+ .build())
+ .build());
Map<Long, List<Long>> referenceMap = DataConversions.asMap(
- new IndexedDataMap<>(new AppendOnlyLog<>(new LongListDataType(), new OnHeapMemory())));
+ IndexedDataMap.<List<Long>>builder()
+ .values(AppendOnlyLog.<List<Long>>builder()
+ .dataType(new LongListDataType())
+ .memory(new OnHeapMemory())
+ .build())
+ .build());
// Import the sample data
ImportOsmPbf.execute(TestFiles.SAMPLE_OSM_PBF, coordinateMap, referenceMap, headerRepository,
diff --git a/baremaps-data/src/main/java/org/apache/baremaps/data/collection/AppendOnlyLog.java b/baremaps-data/src/main/java/org/apache/baremaps/data/collection/AppendOnlyLog.java
index fbb549988..c5e9adbdc 100644
--- a/baremaps-data/src/main/java/org/apache/baremaps/data/collection/AppendOnlyLog.java
+++ b/baremaps-data/src/main/java/org/apache/baremaps/data/collection/AppendOnlyLog.java
@@ -30,11 +30,10 @@ import org.apache.baremaps.data.memory.OffHeapMemory;
import org.apache.baremaps.data.type.DataType;
/**
- * A log of records backed by a {@link DataType} and a {@link Memory}. Elements are appended to the
- * log and can be accessed by their position in the {@link Memory}. Appending elements to the log is
- * thread-safe.
+ * A log of elements that can only be appended to. Elements are stored in memory and can be accessed
+ * by their position. Append operations are thread-safe.
*
- * @param <E> The type of the data.
+ * @param <E> The type of elements in the log
*/
public class AppendOnlyLog<E> implements DataCollection<E> {
@@ -47,21 +46,84 @@ public class AppendOnlyLog<E> implements DataCollection<E> {
private final Lock lock = new ReentrantLock();
/**
- * Constructs an {@link AppendOnlyLog}.
+ * Creates a new builder for an AppendOnlyLog.
*
- * @param dataType the data type
+ * @param <E> the type of elements
+ * @return a new builder
*/
- public AppendOnlyLog(DataType<E> dataType) {
- this(dataType, new OffHeapMemory());
+ public static <E> Builder<E> builder() {
+ return new Builder<>();
}
/**
- * Constructs an append only log.
+ * Builder for AppendOnlyLog.
+ *
+ * @param <E> the type of elements
+ */
+ public static class Builder<E> {
+ private DataType<E> dataType;
+ private Memory<?> memory;
+
+ /**
+ * Sets the data type for the log.
+ *
+ * @param dataType the data type
+ * @return this builder
+ */
+ public Builder<E> dataType(DataType<?> dataType) {
+ @SuppressWarnings("unchecked")
+ DataType<E> castedDataType = (DataType<E>) dataType;
+ this.dataType = castedDataType;
+ return this;
+ }
+
+ /**
+ * Sets the memory for the log.
+ *
+ * @param memory the memory
+ * @return this builder
+ */
+ public Builder<E> memory(Memory<?> memory) {
+ this.memory = memory;
+ return this;
+ }
+
+ /**
+ * Sets the memory for the log values.
+ *
+ * @param memory the memory
+ * @return this builder
+ */
+ public Builder<E> values(Memory<?> memory) {
+ return memory(memory);
+ }
+
+ /**
+ * Builds a new AppendOnlyLog.
+ *
+ * @return a new AppendOnlyLog
+ * @throws IllegalStateException if required parameters are missing
+ */
+ public AppendOnlyLog<E> build() {
+ if (dataType == null) {
+ throw new IllegalStateException("Data type must be specified");
+ }
+
+ if (memory == null) {
+ memory = new OffHeapMemory();
+ }
+
+ return new AppendOnlyLog<>(dataType, memory);
+ }
+ }
+
+ /**
+ * Constructs an AppendOnlyLog.
*
* @param dataType the data type
* @param memory the memory
*/
- public AppendOnlyLog(DataType<E> dataType, Memory<?> memory) {
+ private AppendOnlyLog(DataType<E> dataType, Memory<?> memory) {
this.dataType = dataType;
this.memory = memory;
this.segmentSize = memory.segmentSize();
@@ -70,10 +132,18 @@ public class AppendOnlyLog<E> implements DataCollection<E> {
}
/**
- * Appends the value to the log and returns its position in the memory.
+ * Persists the current size to memory.
+ */
+ public void persistSize() {
+ memory.segment(0).putLong(0, size);
+ }
+
+ /**
+ * Appends an element to the log and returns its position in memory.
*
- * @param value the value
- * @return the position of the value in the memory.
+ * @param value the element to add
+ * @return the position of the element in memory
+ * @throws DataCollectionException if the element is too large for a segment
*/
public long addPositioned(E value) {
int valueSize = dataType.size(value);
@@ -102,10 +172,10 @@ public class AppendOnlyLog<E> implements DataCollection<E> {
}
/**
- * Returns a values at the specified position in the memory.
+ * Returns the element at the specified position in memory.
*
- * @param position the position of the value
- * @return the value
+ * @param position the position of the element
+ * @return the element
*/
public E getPositioned(long position) {
long segmentIndex = position / segmentSize;
@@ -130,32 +200,39 @@ public class AppendOnlyLog<E> implements DataCollection<E> {
public void clear() {
try {
memory.clear();
+ this.size = 0;
+ persistSize();
} catch (IOException e) {
throw new DataCollectionException(e);
}
}
/**
- * Returns an iterator over the values of the log, starting at the beginning of the log. The
- * iterator allows to get the current position in the memory.
+ * Returns an iterator over the elements of this log.
*
- * @return an iterator over the values of the log
+ * @return an iterator over the elements
*/
@Override
public AppendOnlyLogIterator iterator() {
return new AppendOnlyLogIterator(size);
}
+ @Override
+ public void close() throws Exception {
+ try {
+ memory.close();
+ } catch (IOException e) {
+ throw new DataCollectionException(e);
+ }
+ }
+
/**
- * An iterator over the values of the log that can be used to iterate over the values of the log
- * and to get the current position in the memory.
+ * An iterator over the elements in this log.
*/
public class AppendOnlyLogIterator implements Iterator<E> {
private final long size;
-
private long index;
-
private long position;
private AppendOnlyLogIterator(long size) {
@@ -199,9 +276,13 @@ public class AppendOnlyLog<E> implements DataCollection<E> {
return dataType.read(segment, (int) segmentOffset);
}
+ /**
+ * Returns the current position in memory.
+ *
+ * @return the current position
+ */
public long getPosition() {
return position;
}
-
}
}
diff --git a/baremaps-data/src/main/java/org/apache/baremaps/data/collection/DataCollection.java b/baremaps-data/src/main/java/org/apache/baremaps/data/collection/DataCollection.java
index 1189cd846..5c5f549f6 100644
--- a/baremaps-data/src/main/java/org/apache/baremaps/data/collection/DataCollection.java
+++ b/baremaps-data/src/main/java/org/apache/baremaps/data/collection/DataCollection.java
@@ -22,29 +22,31 @@ import java.util.stream.Stream;
import java.util.stream.StreamSupport;
/**
- * A {@code DataCollection<E>} is a group of elements that can be iterated over. It is similar to a
- * {@link java.util.Collection<E> Collection}, but can hold up to {@link Long#MAX_VALUE} elements.
+ * A collection of elements that can be iterated over. Similar to {@link java.util.Collection} but
+ * supports up to {@link Long#MAX_VALUE} elements.
+ *
+ * @param <E> The type of elements in the collection
*/
-public interface DataCollection<E> extends Iterable<E> {
+public interface DataCollection<E> extends Iterable<E>, AutoCloseable {
/**
- * Returns the number of values stored in the data collection.
+ * Returns the number of elements in this collection.
*
- * @return the number of values
+ * @return the number of elements
*/
long size();
/**
- * Returns true if the data collection is empty.
+ * Returns true if this collection contains no elements.
*
- * @return true if the data collection is empty
+ * @return true if this collection is empty
*/
default boolean isEmpty() {
return size() == 0;
}
/**
- * Returns an iterator over the elements in the data collection.
+ * Returns an iterator over the elements in this collection.
*
* @return an iterator
*/
@@ -52,7 +54,7 @@ public interface DataCollection<E> extends Iterable<E> {
Iterator<E> iterator();
/**
- * Returns a spliterator over the elements in the data collection.
+ * Returns a spliterator over the elements in this collection.
*
* @return a spliterator
*/
@@ -62,16 +64,16 @@ public interface DataCollection<E> extends Iterable<E> {
}
/**
- * Returns a stream over the elements in the data collection.
+ * Returns a sequential stream over the elements in this collection.
*
- * @return a stream
+ * @return a sequential stream
*/
default Stream<E> stream() {
return StreamSupport.stream(spliterator(), false);
}
/**
- * Returns a parallel stream over the elements in the data collection.
+ * Returns a parallel stream over the elements in this collection.
*
* @return a parallel stream
*/
@@ -80,20 +82,20 @@ public interface DataCollection<E> extends Iterable<E> {
}
/**
- * Adds a value to the data collection.
+ * Adds an element to this collection.
*
- * @param e the value to add
- * @return true if the data collection has been modified
+ * @param e the element to add
+ * @return true if the collection changed as a result of the call
*/
default boolean add(E e) {
throw new UnsupportedOperationException();
}
/**
- * Adds all the values in the specified collection to the data collection.
+ * Adds all elements from the specified collection to this collection.
*
- * @param c the collection of values to add
- * @return true if the data collection has been modified
+ * @param c the collection of elements to add
+ * @return true if this collection changed as a result of the call
*/
default boolean addAll(Iterable<? extends E> c) {
boolean modified = false;
@@ -106,9 +108,10 @@ public interface DataCollection<E> extends Iterable<E> {
}
/**
- * Returns true if the data collection contains the specified value.
+ * Returns true if this collection contains the specified element.
*
- * @param o the value to search for
+ * @param o the element to check for
+ * @return true if this collection contains the element
*/
default boolean contains(Object o) {
for (E e : this) {
@@ -120,10 +123,10 @@ public interface DataCollection<E> extends Iterable<E> {
}
/**
- * Returns true if the data collection contains all the values in the specified collection.
+ * Returns true if this collection contains all elements in the specified collection.
*
- * @param c the collection of values to search for
- * @return true if the data collection contains all the values
+ * @param c the collection to check against
+ * @return true if this collection contains all elements in the specified collection
*/
default boolean containsAll(Iterable<?> c) {
for (Object o : c) {
@@ -135,7 +138,7 @@ public interface DataCollection<E> extends Iterable<E> {
}
/**
- * Removes all the values from the data collection.
+ * Removes all elements from this collection.
*/
void clear();
diff --git a/baremaps-data/src/main/java/org/apache/baremaps/data/collection/DataCollectionException.java b/baremaps-data/src/main/java/org/apache/baremaps/data/collection/DataCollectionException.java
index a4300ccf8..7720b2023 100644
--- a/baremaps-data/src/main/java/org/apache/baremaps/data/collection/DataCollectionException.java
+++ b/baremaps-data/src/main/java/org/apache/baremaps/data/collection/DataCollectionException.java
@@ -17,35 +17,39 @@
package org.apache.baremaps.data.collection;
-/** Signals that an exception occurred in a store. */
+/**
+ * Exception thrown when an error occurs in a data collection operation.
+ */
public class DataCollectionException extends RuntimeException {
- /** Constructs a {@code DataCollectionException} with {@code null} as its error detail message. */
+ /**
+ * Constructs a new exception with null as its detail message.
+ */
public DataCollectionException() {}
/**
- * Constructs an {@code DataCollectionException} with the specified detail message.
+ * Constructs a new exception with the specified detail message.
*
- * @param message the message
+ * @param message the detail message
*/
public DataCollectionException(String message) {
super(message);
}
/**
- * Constructs a {@code DataCollectionException} with the specified cause.
+ * Constructs a new exception with the specified cause.
*
- * @param cause the cause
+ * @param cause the cause of this exception
*/
public DataCollectionException(Throwable cause) {
super(cause);
}
/**
- * Constructs a {@code DataCollectionException} with the specified detail message and cause.
+ * Constructs a new exception with the specified detail message and cause.
*
- * @param message the message
- * @param cause the cause
+ * @param message the detail message
+ * @param cause the cause of this exception
*/
public DataCollectionException(String message, Throwable cause) {
super(message, cause);
diff --git a/baremaps-data/src/main/java/org/apache/baremaps/data/collection/DataCollectionMapper.java b/baremaps-data/src/main/java/org/apache/baremaps/data/collection/DataCollectionMapper.java
index 970407919..9ab9101c4 100644
--- a/baremaps-data/src/main/java/org/apache/baremaps/data/collection/DataCollectionMapper.java
+++ b/baremaps-data/src/main/java/org/apache/baremaps/data/collection/DataCollectionMapper.java
@@ -22,7 +22,10 @@ import java.util.Iterator;
import java.util.function.Function;
/**
- * A decorator for a table that transforms the geometries of the rows.
+ * A decorator that transforms elements of a data collection using a function.
+ *
+ * @param <S> The source element type
+ * @param <T> The transformed element type
*/
public class DataCollectionMapper<S, T> implements DataCollection<T> {
@@ -31,10 +34,10 @@ public class DataCollectionMapper<S, T> implements DataCollection<T> {
private final Function<S, T> mapper;
/**
- * Constructs a new table decorator.
+ * Constructs a new mapper for a data collection.
*
- * @param collection the table to decorate
- * @param mapper the row transformer
+ * @param collection the source collection
+ * @param mapper the function to transform elements
*/
public DataCollectionMapper(DataCollection<S> collection, Function<S, T> mapper) {
this.collection = collection;
@@ -58,4 +61,9 @@ public class DataCollectionMapper<S, T> implements DataCollection<T> {
public void clear() {
collection.clear();
}
+
+ @Override
+ public void close() throws Exception {
+ collection.close();
+ }
}
diff --git a/baremaps-data/src/main/java/org/apache/baremaps/data/collection/DataConversions.java b/baremaps-data/src/main/java/org/apache/baremaps/data/collection/DataConversions.java
index 593f6acd4..8f1957c16 100644
--- a/baremaps-data/src/main/java/org/apache/baremaps/data/collection/DataConversions.java
+++ b/baremaps-data/src/main/java/org/apache/baremaps/data/collection/DataConversions.java
@@ -21,7 +21,7 @@ import java.util.*;
import java.util.Map.Entry;
/**
- * Utility class for converting between collections and data collections.
+ * Utility class for converting between standard Java collections and data collections.
*/
public class DataConversions {
@@ -30,11 +30,11 @@ public class DataConversions {
}
/**
- * Converts a {@code DataCollection} to a {@code Collection}.
+ * Converts a DataCollection to a Collection.
*
- * @param dataCollection
- * @return
- * @param <E>
+ * @param dataCollection the data collection to convert
+ * @return a Collection view of the data collection
+ * @param <E> the type of elements
*/
public static <E> Collection<E> asCollection(DataCollection<E> dataCollection) {
if (dataCollection instanceof DataCollectionAdapter<E>adapter) {
@@ -45,11 +45,11 @@ public class DataConversions {
}
/**
- * Converts a {@code Collection} to a {@code DataCollection}.
+ * Converts a Collection to a DataCollection.
*
- * @param collection
- * @return
- * @param <E>
+ * @param collection the collection to convert
+ * @return a DataCollection view of the collection
+ * @param <E> the type of elements
*/
public static <E> DataCollection<E> asDataCollection(Collection<E> collection) {
if (collection instanceof CollectionAdapter<E>adapter) {
@@ -60,10 +60,11 @@ public class DataConversions {
}
/**
- * Converts a {@code DataList} to a {@code List}.
+ * Converts a DataList to a List.
*
- * @param dataList the data list
- * @return the list
+ * @param dataList the data list to convert
+ * @return a List view of the data list
+ * @param <E> the type of elements
*/
public static <E> List<E> asList(DataList<E> dataList) {
if (dataList instanceof DataListAdapter<E>adapter) {
@@ -74,10 +75,11 @@ public class DataConversions {
}
/**
- * Converts a {@code List} to a {@code DataList}.
+ * Converts a List to a DataList.
*
- * @param list the list
- * @return the data list
+ * @param list the list to convert
+ * @return a DataList view of the list
+ * @param <E> the type of elements
*/
public static <E> DataList<E> asDataList(List<E> list) {
if (list instanceof ListAdapter<E>adapter) {
@@ -88,10 +90,12 @@ public class DataConversions {
}
/**
- * Converts a {@code DataMap} to a {@code Map}.
+ * Converts a DataMap to a Map.
*
- * @param dataMap the data map
- * @return the map
+ * @param dataMap the data map to convert
+ * @return a Map view of the data map
+ * @param <K> the type of keys
+ * @param <V> the type of values
*/
public static <K, V> Map<K, V> asMap(DataMap<K, V> dataMap) {
if (dataMap instanceof DataMapAdapter<K, V>adapter) {
@@ -102,10 +106,12 @@ public class DataConversions {
}
/**
- * Converts a {@code Map} to a {@code DataMap}.
+ * Converts a Map to a DataMap.
*
- * @param map the map
- * @return the data map
+ * @param map the map to convert
+ * @return a DataMap view of the map
+ * @param <K> the type of keys
+ * @param <V> the type of values
*/
public static <K, V> DataMap<K, V> asDataMap(Map<K, V> map) {
if (map instanceof MapAdapter<K, V>adapter) {
@@ -163,6 +169,13 @@ public class DataConversions {
public Iterator<E> iterator() {
return collection.iterator();
}
+
+ @Override
+ public void close() throws Exception {
+ if (collection instanceof AutoCloseable) {
+ ((AutoCloseable) collection).close();
+ }
+ }
}
private static class ListAdapter<E> extends AbstractList<E> {
@@ -251,6 +264,13 @@ public class DataConversions {
public int hashCode() {
return list.hashCode();
}
+
+ @Override
+ public void close() throws Exception {
+ if (list instanceof AutoCloseable) {
+ ((AutoCloseable) list).close();
+ }
+ }
}
private static class MapAdapter<K, V> extends AbstractMap<K, V> {
@@ -361,6 +381,13 @@ public class DataConversions {
public int hashCode() {
return map.hashCode();
}
+
+ @Override
+ public void close() throws Exception {
+ if (map instanceof AutoCloseable) {
+ ((AutoCloseable) map).close();
+ }
+ }
}
}
diff --git a/baremaps-data/src/main/java/org/apache/baremaps/data/collection/DataList.java b/baremaps-data/src/main/java/org/apache/baremaps/data/collection/DataList.java
index de711d101..39c6c95c6 100644
--- a/baremaps-data/src/main/java/org/apache/baremaps/data/collection/DataList.java
+++ b/baremaps-data/src/main/java/org/apache/baremaps/data/collection/DataList.java
@@ -23,19 +23,18 @@ import java.util.Iterator;
import java.util.NoSuchElementException;
/**
- * A {@code DataList<E>} is a sequence of elements that can be iterated over and accessed by index.
- * It is similar to a {@link java.util.List<E> List}, but can hold up to {@link Long#MAX_VALUE}
- * elements.
+ * A sequence of elements that can be accessed by index. Similar to {@link java.util.List} but
+ * supports up to {@link Long#MAX_VALUE} elements.
*
- * @param <E> The type of the elements.
+ * @param <E> The type of elements in the list
*/
public interface DataList<E> extends DataCollection<E> {
/**
- * Adds a value to the data list and returns its index.
+ * Adds an element to this list and returns its index.
*
- * @param value the value
- * @return the index of the value.
+ * @param value the element to add
+ * @return the index of the added element
*/
long addIndexed(E value);
@@ -47,18 +46,18 @@ public interface DataList<E> extends DataCollection<E> {
}
/**
- * Sets the value at the specified index
+ * Sets the element at the specified index.
*
* @param index the index
- * @param value the value
+ * @param value the element to set
*/
void set(long index, E value);
/**
- * Returns the value at the specified index.
+ * Returns the element at the specified index.
*
* @param index the index
- * @return the value
+ * @return the element at the specified index
*/
E get(long index);
diff --git a/baremaps-data/src/main/java/org/apache/baremaps/data/collection/DataMap.java b/baremaps-data/src/main/java/org/apache/baremaps/data/collection/DataMap.java
index 1a9095246..ecd4738d6 100644
--- a/baremaps-data/src/main/java/org/apache/baremaps/data/collection/DataMap.java
+++ b/baremaps-data/src/main/java/org/apache/baremaps/data/collection/DataMap.java
@@ -25,34 +25,34 @@ import java.util.Map.Entry;
import java.util.function.BiConsumer;
/**
- * A {@code DataMap<E>} maps keys to values. It is similar to a {@link java.util.Map<K, V> Map}, but
- * can hold up to {@link Long#MAX_VALUE} entries.
+ * A map that associates keys with values. Similar to {@link java.util.Map} but supports up to
+ * {@link Long#MAX_VALUE} entries.
*
- * @param <K> The type of the keys.
- * @param <V> The type of the values.
+ * @param <K> The type of keys in the map
+ * @param <V> The type of values in the map
*/
-public interface DataMap<K, V> {
+public interface DataMap<K, V> extends AutoCloseable {
/**
- * Returns the number of values stored in the data map.
+ * Returns the number of key-value mappings in this map.
*
- * @return the number of values
+ * @return the number of key-value mappings
*/
long size();
/**
- * Returns the value associated with the specified key or null if the key is not present.
+ * Returns the value associated with the specified key, or null if no mapping exists.
*
* @param key the key
- * @return the value
+ * @return the value associated with the key, or null if no mapping exists
*/
V get(Object key);
/**
- * Returns the values associated with the specified keys or null if the key is not present.
+ * Returns the values associated with the specified keys, or null for keys with no mapping.
*
* @param keys the keys
- * @return the values
+ * @return the values associated with the keys
*/
default Iterable<V> getAll(Iterable<K> keys) {
List<V> values = new ArrayList<>();
@@ -61,105 +61,105 @@ public interface DataMap<K, V> {
}
/**
- * Associates the specified value with the specified key in the data map.
+ * Associates the specified value with the specified key in this map.
*
* @param key the key
* @param value the value
- * @return the previous value associated with the key, or null if there was no mapping for the key
+ * @return the previous value associated with the key, or null if there was no mapping
*/
V put(K key, V value);
/**
- * Associates the specified values with the specified keys in the data map.
+ * Adds all entries from the specified iterable to this map.
*
- * @param entries the entries
+ * @param entries the entries to add
*/
default void putAll(Iterable<Entry<K, V>> entries) {
entries.forEach(entry -> put(entry.getKey(), entry.getValue()));
}
/**
- * Returns true if the data map contains a mapping for the specified key.
+ * Returns true if this map contains a mapping for the specified key.
*
- * @param key the key
- * @return true if the data map contains a mapping for the key
+ * @param key the key to check
+ * @return true if this map contains a mapping for the key
*/
boolean containsKey(Object key);
/**
- * Returns true if the data map contains a mapping for the specified value.
+ * Returns true if this map maps one or more keys to the specified value.
*
- * @param value the value
- * @return true if the data map contains a mapping for the value
+ * @param value the value to check
+ * @return true if this map maps one or more keys to the value
*/
boolean containsValue(V value);
/**
- * Clears the data map.
+ * Removes all mappings from this map.
*/
void clear();
/**
- * Returns true if the data map contains no elements.
+ * Returns true if this map contains no mappings.
*
- * @return true if the data map contains no elements
+ * @return true if this map contains no mappings
*/
default boolean isEmpty() {
return size() == 0;
}
/**
- * Returns an iterator over the keys of the data map.
+ * Returns an iterator over the keys in this map.
*
- * @return an iterator
+ * @return an iterator over the keys
*/
Iterator<K> keyIterator();
/**
- * Returns an iterable over the keys of the data map.
+ * Returns an iterable over the keys in this map.
*
- * @return an iterable
+ * @return an iterable over the keys
*/
default Iterable<K> keys() {
return this::keyIterator;
}
/**
- * Returns an iterator over the values of the data map.
+ * Returns an iterator over the values in this map.
*
- * @return an iterator
+ * @return an iterator over the values
*/
Iterator<V> valueIterator();
/**
- * Returns an iterable over the values of the data map.
+ * Returns an iterable over the values in this map.
*
- * @return an iterable
+ * @return an iterable over the values
*/
default Iterable<V> values() {
return this::valueIterator;
}
/**
- * Returns an iterator over the entries of the data map.
+ * Returns an iterator over the entries in this map.
*
- * @return an iterator
+ * @return an iterator over the entries
*/
Iterator<Entry<K, V>> entryIterator();
/**
- * Returns an iterable over the entries of the data map.
+ * Returns an iterable over the entries in this map.
*
- * @return an iterable
+ * @return an iterable over the entries
*/
default Iterable<Entry<K, V>> entries() {
return this::entryIterator;
}
/**
- * Performs the given action for each entry in the data map.
+ * Performs the given action for each entry in this map.
*
- * @param action the action to be performed
+ * @param action the action to perform on each entry
*/
default void forEach(BiConsumer<? super K, ? super V> action) {
for (Entry<K, V> entry : entries()) {
diff --git a/baremaps-data/src/main/java/org/apache/baremaps/data/collection/DirectHashDataMap.java b/baremaps-data/src/main/java/org/apache/baremaps/data/collection/DirectHashDataMap.java
new file mode 100644
index 000000000..2fb63e086
--- /dev/null
+++ b/baremaps-data/src/main/java/org/apache/baremaps/data/collection/DirectHashDataMap.java
@@ -0,0 +1,496 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to you 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.
+ */
+
+package org.apache.baremaps.data.collection;
+
+import java.nio.ByteBuffer;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.NoSuchElementException;
+import java.util.Objects;
+import org.apache.baremaps.data.memory.Memory;
+import org.apache.baremaps.data.type.FixedSizeDataType;
+
+/**
+ * A map that uses direct hashing with open addressing and linear probing. Provides O(1) access time
+ * for both get and put operations with a fixed capacity.
+ *
+ * @param <V> the type of values in the map
+ */
+public class DirectHashDataMap<V> implements DataMap<Long, V> {
+
+ private static final long EMPTY_KEY = Long.MIN_VALUE;
+ private static final long TOMBSTONE = Long.MIN_VALUE + 1;
+
+ private final FixedSizeDataType<V> dataType;
+ private final FixedSizeDataType<Long> keyType;
+ private final Memory<?> keyMemory;
+ private final Memory<?> valueMemory;
+
+ private final long capacity;
+ private final int valueSize;
+ private final int keySize;
+
+ private long size;
+
+ /**
+ * Creates a new builder for a DirectHashDataMap.
+ *
+ * @param <V> the type of values
+ * @return a new builder
+ */
+ public static <V> Builder<V> builder() {
+ return new Builder<>();
+ }
+
+ /**
+ * Builder for DirectHashDataMap.
+ *
+ * @param <V> the type of values
+ */
+ public static class Builder<V> {
+ private FixedSizeDataType<Long> keyType;
+ private FixedSizeDataType<V> dataType;
+ private Memory<?> keyMemory;
+ private Memory<?> valueMemory;
+ private long capacity;
+
+ /**
+ * Sets the key type for the map.
+ *
+ * @param keyType the data type for keys
+ * @return this builder
+ */
+ public Builder<V> keyType(FixedSizeDataType<Long> keyType) {
+ this.keyType = keyType;
+ return this;
+ }
+
+ /**
+ * Sets the data type for the map.
+ *
+ * @param dataType the data type for values
+ * @return this builder
+ */
+ public Builder<V> dataType(FixedSizeDataType<V> dataType) {
+ this.dataType = dataType;
+ return this;
+ }
+
+ /**
+ * Sets the key memory for the map.
+ *
+ * @param keyMemory the memory for keys
+ * @return this builder
+ */
+ public Builder<V> keyMemory(Memory<?> keyMemory) {
+ this.keyMemory = keyMemory;
+ return this;
+ }
+
+ /**
+ * Sets the value memory for the map.
+ *
+ * @param valueMemory the memory for values
+ * @return this builder
+ */
+ public Builder<V> valueMemory(Memory<?> valueMemory) {
+ this.valueMemory = valueMemory;
+ return this;
+ }
+
+ /**
+ * Sets the capacity for the map.
+ *
+ * @param capacity the fixed capacity of the map
+ * @return this builder
+ */
+ public Builder<V> capacity(long capacity) {
+ this.capacity = capacity;
+ return this;
+ }
+
+ /**
+ * Builds a new DirectHashDataMap.
+ *
+ * @return a new DirectHashDataMap
+ * @throws IllegalStateException if any required parameter is missing
+ */
+ public DirectHashDataMap<V> build() {
+ if (keyType == null) {
+ throw new IllegalStateException("Key type must be specified");
+ }
+ if (dataType == null) {
+ throw new IllegalStateException("Data type must be specified");
+ }
+ if (keyMemory == null) {
+ throw new IllegalStateException("Key memory must be specified");
+ }
+ if (valueMemory == null) {
+ throw new IllegalStateException("Value memory must be specified");
+ }
+ if (capacity <= 0) {
+ throw new IllegalStateException("Capacity must be greater than zero");
+ }
+
+ return new DirectHashDataMap<>(keyType, dataType, keyMemory, valueMemory, capacity);
+ }
+ }
+
+ /**
+ * Constructs a DirectHashDataMap with the specified capacity.
+ *
+ * @param keyType the data type for keys
+ * @param dataType the data type for values
+ * @param keyMemory the memory for keys
+ * @param valueMemory the memory for values
+ * @param capacity the fixed capacity of the map
+ */
+ private DirectHashDataMap(
+ FixedSizeDataType<Long> keyType,
+ FixedSizeDataType<V> dataType,
+ Memory<?> keyMemory,
+ Memory<?> valueMemory,
+ long capacity) {
+ this.keyType = keyType;
+ this.dataType = dataType;
+ this.keyMemory = keyMemory;
+ this.valueMemory = valueMemory;
+ this.capacity = capacity;
+ this.keySize = keyType.size();
+ this.valueSize = dataType.size();
+ this.size = 0;
+
+ // Initialize all keys to EMPTY_KEY
+ for (long i = 0; i < capacity; i++) {
+ storeKey(i, EMPTY_KEY);
+ }
+ }
+
+ /**
+ * Computes the hash value for a key.
+ *
+ * @param key the key to hash
+ * @return the hash value
+ */
+ private long hash(long key) {
+ // Using a variant of the Knuth multiplicative method
+ // with the golden ratio
+ final long GOLDEN_RATIO = 0x9E3779B97F4A7C15L;
+ return ((key * GOLDEN_RATIO) >>> 16) % capacity;
+ }
+
+ /**
+ * Finds the slot for a key, either for retrieval or insertion.
+ *
+ * @param key the key to find
+ * @param forInsertion whether we're finding for insertion or retrieval
+ * @return the slot index or -1 if not found and not for insertion
+ */
+ private long findSlot(long key, boolean forInsertion) {
+ long index = hash(key);
+ long tombstoneSlot = -1;
+
+ // Linear probing to handle collisions
+ for (long i = 0; i < capacity; i++) {
+ long currentIndex = (index + i) % capacity;
+ long currentKey = readKey(currentIndex);
+
+ if (currentKey == EMPTY_KEY) {
+ // Found empty slot
+ return forInsertion ? (tombstoneSlot != -1 ? tombstoneSlot : currentIndex) : -1;
+ } else if (currentKey == TOMBSTONE) {
+ // Mark first tombstone for possible reuse
+ if (tombstoneSlot == -1) {
+ tombstoneSlot = currentIndex;
+ }
+ } else if (currentKey == key) {
+ // Found the key
+ return currentIndex;
+ }
+ }
+
+ // If we're inserting and found a tombstone earlier, use that
+ if (forInsertion && tombstoneSlot != -1) {
+ return tombstoneSlot;
+ }
+
+ // Map is full or key not found
+ return -1;
+ }
+
+ /**
+ * Reads a key from the specified slot.
+ *
+ * @param slot the slot index
+ * @return the key at the slot
+ */
+ private long readKey(long slot) {
+ long position = slot * keySize;
+ int segmentIndex = (int) (position >>> keyMemory.segmentShift());
+ int segmentOffset = (int) (position & keyMemory.segmentMask());
+ ByteBuffer segment = keyMemory.segment(segmentIndex);
+ return keyType.read(segment, segmentOffset);
+ }
+
+ /**
+ * Stores a key at the specified slot.
+ *
+ * @param slot the slot index
+ * @param key the key to store
+ */
+ private void storeKey(long slot, long key) {
+ long position = slot * keySize;
+ int segmentIndex = (int) (position >>> keyMemory.segmentShift());
+ int segmentOffset = (int) (position & keyMemory.segmentMask());
+ ByteBuffer segment = keyMemory.segment(segmentIndex);
+ keyType.write(segment, segmentOffset, key);
+ }
+
+ /**
+ * Reads a value from the specified slot.
+ *
+ * @param slot the slot index
+ * @return the value at the slot
+ */
+ private V readValue(long slot) {
+ long position = slot * valueSize;
+ int segmentIndex = (int) (position >>> valueMemory.segmentShift());
+ int segmentOffset = (int) (position & valueMemory.segmentMask());
+ ByteBuffer segment = valueMemory.segment(segmentIndex);
+ return dataType.read(segment, segmentOffset);
+ }
+
+ /**
+ * Stores a value at the specified slot.
+ *
+ * @param slot the slot index
+ * @param value the value to store
+ */
+ private void storeValue(long slot, V value) {
+ long position = slot * valueSize;
+ int segmentIndex = (int) (position >>> valueMemory.segmentShift());
+ int segmentOffset = (int) (position & valueMemory.segmentMask());
+ ByteBuffer segment = valueMemory.segment(segmentIndex);
+ dataType.write(segment, segmentOffset, value);
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public V put(Long key, V value) {
+ Objects.requireNonNull(key, "Key cannot be null");
+ Objects.requireNonNull(value, "Value cannot be null");
+
+ if (key == EMPTY_KEY || key == TOMBSTONE) {
+ throw new IllegalArgumentException("Reserved key value: " + key);
+ }
+
+ long slot = findSlot(key, true);
+ if (slot == -1) {
+ throw new IllegalStateException("Map is full");
+ }
+
+ long existingKey = readKey(slot);
+ V previousValue = null;
+
+ if (existingKey != EMPTY_KEY && existingKey != TOMBSTONE) {
+ // Slot contains an existing key
+ previousValue = readValue(slot);
+ } else {
+ // New entry
+ size++;
+ }
+
+ storeKey(slot, key);
+ storeValue(slot, value);
+
+ return previousValue;
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public V get(Object keyObj) {
+ if (!(keyObj instanceof Long key)) {
+ return null;
+ }
+
+ if (key == EMPTY_KEY || key == TOMBSTONE) {
+ return null;
+ }
+
+ long slot = findSlot(key, false);
+ if (slot == -1) {
+ return null;
+ }
+
+ return readValue(slot);
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public boolean containsKey(Object keyObj) {
+ if (!(keyObj instanceof Long key)) {
+ return false;
+ }
+
+ if (key == EMPTY_KEY || key == TOMBSTONE) {
+ return false;
+ }
+
+ return findSlot(key, false) != -1;
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public boolean containsValue(Object value) {
+ if (value == null) {
+ return false;
+ }
+
+ Iterator<V> iterator = valueIterator();
+ while (iterator.hasNext()) {
+ if (value.equals(iterator.next())) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public long size() {
+ return size;
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public void clear() {
+ for (long i = 0; i < capacity; i++) {
+ storeKey(i, EMPTY_KEY);
+ }
+ size = 0;
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public Iterator<Long> keyIterator() {
+ return new Iterator<>() {
+ private long currentIndex = 0;
+ private long returnedCount = 0;
+
+ @Override
+ public boolean hasNext() {
+ return returnedCount < size;
+ }
+
+ @Override
+ public Long next() {
+ if (!hasNext()) {
+ throw new NoSuchElementException();
+ }
+
+ while (currentIndex < capacity) {
+ long key = readKey(currentIndex++);
+ if (key != EMPTY_KEY && key != TOMBSTONE) {
+ returnedCount++;
+ return key;
+ }
+ }
+
+ throw new NoSuchElementException();
+ }
+ };
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public Iterator<V> valueIterator() {
+ return new Iterator<>() {
+ private long currentIndex = 0;
+ private long returnedCount = 0;
+
+ @Override
+ public boolean hasNext() {
+ return returnedCount < size;
+ }
+
+ @Override
+ public V next() {
+ if (!hasNext()) {
+ throw new NoSuchElementException();
+ }
+
+ while (currentIndex < capacity) {
+ long key = readKey(currentIndex);
+ if (key != EMPTY_KEY && key != TOMBSTONE) {
+ returnedCount++;
+ return readValue(currentIndex++);
+ }
+ currentIndex++;
+ }
+
+ throw new NoSuchElementException();
+ }
+ };
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public Iterator<Entry<Long, V>> entryIterator() {
+ return new Iterator<>() {
+ private long currentIndex = 0;
+ private long returnedCount = 0;
+
+ @Override
+ public boolean hasNext() {
+ return returnedCount < size;
+ }
+
+ @Override
+ public Entry<Long, V> next() {
+ if (!hasNext()) {
+ throw new NoSuchElementException();
+ }
+
+ while (currentIndex < capacity) {
+ long key = readKey(currentIndex);
+ if (key != EMPTY_KEY && key != TOMBSTONE) {
+ V value = readValue(currentIndex);
+ currentIndex++;
+ returnedCount++;
+ return Map.entry(key, value);
+ }
+ currentIndex++;
+ }
+
+ throw new NoSuchElementException();
+ }
+ };
+ }
+
+ @Override
+ public void close() throws Exception {
+ try {
+ keyMemory.close();
+ valueMemory.close();
+ } catch (Exception e) {
+ throw new DataCollectionException(e);
+ }
+ }
+}
diff --git a/baremaps-data/src/main/java/org/apache/baremaps/data/collection/FixedSizeDataList.java b/baremaps-data/src/main/java/org/apache/baremaps/data/collection/FixedSizeDataList.java
index 1d5d01dc9..5c7b57478 100644
--- a/baremaps-data/src/main/java/org/apache/baremaps/data/collection/FixedSizeDataList.java
+++ b/baremaps-data/src/main/java/org/apache/baremaps/data/collection/FixedSizeDataList.java
@@ -26,35 +26,85 @@ import org.apache.baremaps.data.memory.OffHeapMemory;
import org.apache.baremaps.data.type.FixedSizeDataType;
/**
- * A {@link DataList} that can hold a large number of fixed size data elements. This data list is
- * backed by a memory that can be either heap, off-heap, or memory mapped.
+ * A list that stores fixed-size elements in memory. Elements can be stored in heap memory, off-heap
+ * memory, or memory-mapped files.
*
- * @param <E> The type of the elements.
+ * @param <E> The type of elements in the list
*/
public class FixedSizeDataList<E> implements DataList<E> {
private final FixedSizeDataType<E> dataType;
-
private final Memory<?> memory;
-
private AtomicLong size;
/**
- * Constructs a {@link FixedSizeDataList}.
+ * Creates a new builder for a FixedSizeDataList.
*
- * @param dataType the data type
+ * @param <E> the type of elements
+ * @return a new builder
+ */
+ public static <E> Builder<E> builder() {
+ return new Builder<>();
+ }
+
+ /**
+ * Builder for FixedSizeDataList.
+ *
+ * @param <E> the type of elements
*/
- public FixedSizeDataList(FixedSizeDataType<E> dataType) {
- this(dataType, new OffHeapMemory());
+ public static class Builder<E> {
+ private FixedSizeDataType<E> dataType;
+ private Memory<?> memory;
+
+ /**
+ * Sets the data type for the list.
+ *
+ * @param dataType the data type
+ * @return this builder
+ */
+ public Builder<E> dataType(FixedSizeDataType<E> dataType) {
+ this.dataType = dataType;
+ return this;
+ }
+
+ /**
+ * Sets the memory for the list.
+ *
+ * @param memory the memory
+ * @return this builder
+ */
+ public Builder<E> memory(Memory<?> memory) {
+ this.memory = memory;
+ return this;
+ }
+
+ /**
+ * Builds a new FixedSizeDataList.
+ *
+ * @return a new FixedSizeDataList
+ * @throws IllegalStateException if the data type is missing
+ */
+ public FixedSizeDataList<E> build() {
+ if (dataType == null) {
+ throw new IllegalStateException("Data type must be specified");
+ }
+
+ if (memory == null) {
+ memory = new OffHeapMemory();
+ }
+
+ return new FixedSizeDataList<>(dataType, memory);
+ }
}
/**
- * Constructs a list.
+ * Constructs a FixedSizeDataList.
*
* @param dataType the data type
* @param memory the memory
+ * @throws DataCollectionException if the data type is too large for the memory segment size
*/
- public FixedSizeDataList(FixedSizeDataType<E> dataType, Memory<?> memory) {
+ private FixedSizeDataList(FixedSizeDataType<E> dataType, Memory<?> memory) {
if (dataType.size() > memory.segmentSize()) {
throw new DataCollectionException("The segment size is too small for the data type");
}
@@ -63,6 +113,12 @@ public class FixedSizeDataList<E> implements DataList<E> {
this.size = new AtomicLong(0);
}
+ /**
+ * Writes an element at the specified index.
+ *
+ * @param index the index
+ * @param value the element to write
+ */
private void write(long index, E value) {
long position = index * dataType.size();
int segmentIndex = (int) (position / memory.segmentSize());
@@ -109,4 +165,13 @@ public class FixedSizeDataList<E> implements DataList<E> {
public void clear() {
size.set(0);
}
+
+ @Override
+ public void close() throws Exception {
+ try {
+ memory.close();
+ } catch (Exception e) {
+ throw new DataCollectionException(e);
+ }
+ }
}
diff --git a/baremaps-data/src/main/java/org/apache/baremaps/data/collection/IndexedDataList.java b/baremaps-data/src/main/java/org/apache/baremaps/data/collection/IndexedDataList.java
index dbe7e555d..1a14640f5 100644
--- a/baremaps-data/src/main/java/org/apache/baremaps/data/collection/IndexedDataList.java
+++ b/baremaps-data/src/main/java/org/apache/baremaps/data/collection/IndexedDataList.java
@@ -22,33 +22,85 @@ package org.apache.baremaps.data.collection;
import org.apache.baremaps.data.type.LongDataType;
/**
- * A data list that can hold a large number of variable size data elements. This data list is backed
- * by an index and a buffer that can be either heap, off-heap, or memory mapped.
+ * A list that stores variable-size elements using an index. Elements are stored in an append-only
+ * log with fixed indices for fast access.
*
- * @param <E> The type of the elements.
+ * @param <E> The type of elements in the list
*/
public class IndexedDataList<E> implements DataList<E> {
private final DataList<Long> index;
-
private final AppendOnlyLog<E> values;
/**
- * Constructs a {@link IndexedDataList}.
+ * Creates a new builder for an IndexedDataList.
*
- * @param values the values
+ * @param <E> the type of elements
+ * @return a new builder
*/
- public IndexedDataList(AppendOnlyLog<E> values) {
- this(new MemoryAlignedDataList<>(new LongDataType()), values);
+ public static <E> Builder<E> builder() {
+ return new Builder<>();
}
/**
- * Constructs a {@link IndexedDataList}.
+ * Builder for IndexedDataList.
+ *
+ * @param <E> the type of elements
+ */
+ public static class Builder<E> {
+ private DataList<Long> index;
+ private AppendOnlyLog<E> values;
+
+ /**
+ * Sets the index for the list.
+ *
+ * @param index the index
+ * @return this builder
+ */
+ public Builder<E> index(DataList<Long> index) {
+ this.index = index;
+ return this;
+ }
+
+ /**
+ * Sets the values for the list.
+ *
+ * @param values the values
+ * @return this builder
+ */
+ public Builder<E> values(AppendOnlyLog<E> values) {
+ this.values = values;
+ return this;
+ }
+
+ /**
+ * Builds a new IndexedDataList.
+ *
+ * @return a new IndexedDataList
+ * @throws IllegalStateException if values are missing
+ */
+ public IndexedDataList<E> build() {
+ if (values == null) {
+ throw new IllegalStateException("Values must be specified");
+ }
+
+ if (index == null) {
+ index = MemoryAlignedDataList.<Long>builder()
+ .dataType(new LongDataType())
+ .build();
+ }
+
+ return new IndexedDataList<>(index, values);
+ }
+ }
+
+ /**
+ * Constructs an IndexedDataList.
*
* @param index the index
* @param values the values
*/
- public IndexedDataList(DataList<Long> index, AppendOnlyLog<E> values) {
+ private IndexedDataList(DataList<Long> index, AppendOnlyLog<E> values) {
this.index = index;
this.values = values;
}
@@ -86,4 +138,14 @@ public class IndexedDataList<E> implements DataList<E> {
index.clear();
values.clear();
}
+
+ @Override
+ public void close() throws Exception {
+ try {
+ index.close();
+ values.close();
+ } catch (Exception e) {
+ throw new DataCollectionException(e);
+ }
+ }
}
diff --git a/baremaps-data/src/main/java/org/apache/baremaps/data/collection/IndexedDataMap.java b/baremaps-data/src/main/java/org/apache/baremaps/data/collection/IndexedDataMap.java
index f1c6d546f..949d2dd90 100644
--- a/baremaps-data/src/main/java/org/apache/baremaps/data/collection/IndexedDataMap.java
+++ b/baremaps-data/src/main/java/org/apache/baremaps/data/collection/IndexedDataMap.java
@@ -26,33 +26,83 @@ import java.util.Map;
import java.util.Map.Entry;
/**
- * A {@link DataMap} that can hold a large number of variable size data elements. This data map is
- * backed by an index and a buffer that can be either heap, off-heap, or memory mapped.
+ * A map that stores variable-size values using an index. Values are stored in an append-only log
+ * with indices for fast access.
*
- * @param <E> The type of the elements.
+ * @param <E> The type of values in the map
*/
public class IndexedDataMap<E> implements DataMap<Long, E> {
private final Map<Long, Long> index;
-
private final AppendOnlyLog<E> values;
/**
- * Constructs a {@link IndexedDataMap}.
+ * Creates a new builder for an IndexedDataMap.
*
- * @param values the values
+ * @param <E> the type of values
+ * @return a new builder
+ */
+ public static <E> Builder<E> builder() {
+ return new Builder<>();
+ }
+
+ /**
+ * Builder for IndexedDataMap.
+ *
+ * @param <E> the type of values
*/
- public IndexedDataMap(AppendOnlyLog<E> values) {
- this(new HashMap<>(), values);
+ public static class Builder<E> {
+ private Map<Long, Long> index;
+ private AppendOnlyLog<E> values;
+
+ /**
+ * Sets the index for the map.
+ *
+ * @param index the index
+ * @return this builder
+ */
+ public Builder<E> index(Map<Long, Long> index) {
+ this.index = index;
+ return this;
+ }
+
+ /**
+ * Sets the values for the map.
+ *
+ * @param values the values
+ * @return this builder
+ */
+ public Builder<E> values(AppendOnlyLog<E> values) {
+ this.values = values;
+ return this;
+ }
+
+ /**
+ * Builds a new IndexedDataMap.
+ *
+ * @return a new IndexedDataMap
+ * @throws IllegalStateException if values are missing
+ */
+ public IndexedDataMap<E> build() {
+ if (values == null) {
+ throw new IllegalStateException("Values must be specified");
+ }
+
+ if (index == null) {
+ index = new HashMap<>();
+ }
+
+ return new IndexedDataMap<>(index, values);
+ }
}
/**
- * Constructs a {@link IndexedDataMap}.
+ * Constructs an IndexedDataMap.
*
* @param index the index
* @param values the values
*/
- public IndexedDataMap(Map<Long, Long> index, AppendOnlyLog<E> values) {
+ private IndexedDataMap(Map<Long, Long> index, AppendOnlyLog<E> values) {
this.index = index;
this.values = values;
}
@@ -121,4 +171,13 @@ public class IndexedDataMap<E> implements DataMap<Long, E> {
index.clear();
values.clear();
}
+
+ @Override
+ public void close() throws Exception {
+ try {
+ values.close();
+ } catch (Exception e) {
+ throw new DataCollectionException(e);
+ }
+ }
}
diff --git a/baremaps-data/src/main/java/org/apache/baremaps/data/collection/MemoryAlignedDataList.java b/baremaps-data/src/main/java/org/apache/baremaps/data/collection/MemoryAlignedDataList.java
index e29f33839..b60294e6b 100644
--- a/baremaps-data/src/main/java/org/apache/baremaps/data/collection/MemoryAlignedDataList.java
+++ b/baremaps-data/src/main/java/org/apache/baremaps/data/collection/MemoryAlignedDataList.java
@@ -28,41 +28,89 @@ import org.apache.baremaps.data.memory.OffHeapMemory;
import org.apache.baremaps.data.type.FixedSizeDataType;
/**
- * A {@link DataList} that can hold a large number of fixed-size memory-aligned data elements. This
- * data list is backed by a memory that can be either heap, off-heap, or memory mapped.
+ * A list that stores fixed-size memory-aligned elements. Optimized for performance with bit-shift
+ * operations for memory addressing.
*
- * @param <E> The type of the elements.
+ * @param <E> The type of elements in the list
*/
public class MemoryAlignedDataList<E> implements DataList<E> {
private final FixedSizeDataType<E> dataType;
-
private final Memory<?> memory;
-
private final int valueShift;
-
private final long segmentShift;
-
private final long segmentMask;
-
private AtomicLong size;
/**
- * Constructs a {@link MemoryAlignedDataList}.
+ * Creates a new builder for a MemoryAlignedDataList.
*
- * @param dataType the data type
+ * @param <E> the type of elements
+ * @return a new builder
*/
- public MemoryAlignedDataList(FixedSizeDataType<E> dataType) {
- this(dataType, new OffHeapMemory());
+ public static <E> Builder<E> builder() {
+ return new Builder<>();
}
/**
- * Constructs a {@link MemoryAlignedDataList}.
+ * Builder for MemoryAlignedDataList.
+ *
+ * @param <E> the type of elements
+ */
+ public static class Builder<E> {
+ private FixedSizeDataType<E> dataType;
+ private Memory<?> memory;
+
+ /**
+ * Sets the data type for the list.
+ *
+ * @param dataType the data type
+ * @return this builder
+ */
+ public Builder<E> dataType(FixedSizeDataType<E> dataType) {
+ this.dataType = dataType;
+ return this;
+ }
+
+ /**
+ * Sets the memory for the list.
+ *
+ * @param memory the memory
+ * @return this builder
+ */
+ public Builder<E> memory(Memory<?> memory) {
+ this.memory = memory;
+ return this;
+ }
+
+ /**
+ * Builds a new MemoryAlignedDataList.
+ *
+ * @return a new MemoryAlignedDataList
+ * @throws IllegalStateException if the data type is missing
+ */
+ public MemoryAlignedDataList<E> build() {
+ if (dataType == null) {
+ throw new IllegalStateException("Data type must be specified");
+ }
+
+ if (memory == null) {
+ memory = new OffHeapMemory();
+ }
+
+ return new MemoryAlignedDataList<>(dataType, memory);
+ }
+ }
+
+ /**
+ * Constructs a MemoryAlignedDataList.
*
* @param dataType the data type
* @param memory the memory
+ * @throws DataCollectionException if memory and data type size requirements are not met
+ * @throws IllegalArgumentException if data type size is not a power of 2
*/
- public MemoryAlignedDataList(FixedSizeDataType<E> dataType, Memory<?> memory) {
+ private MemoryAlignedDataList(FixedSizeDataType<E> dataType, Memory<?> memory) {
if (dataType.size() > memory.segmentSize()) {
throw new DataCollectionException("The segment size is too small for the data type");
}
@@ -80,6 +128,12 @@ public class MemoryAlignedDataList<E> implements DataList<E> {
this.size = new AtomicLong(0);
}
+ /**
+ * Writes an element at the specified index.
+ *
+ * @param index the index
+ * @param value the element to write
+ */
private void write(long index, E value) {
long position = index << valueShift;
int segmentIndex = (int) (position >>> segmentShift);
@@ -129,4 +183,12 @@ public class MemoryAlignedDataList<E> implements DataList<E> {
}
}
+ @Override
+ public void close() throws Exception {
+ try {
+ memory.close();
+ } catch (IOException e) {
+ throw new MemoryException(e);
+ }
+ }
}
diff --git a/baremaps-data/src/main/java/org/apache/baremaps/data/collection/MemoryAlignedDataMap.java b/baremaps-data/src/main/java/org/apache/baremaps/data/collection/MemoryAlignedDataMap.java
index aeeea0107..1fbd9abab 100644
--- a/baremaps-data/src/main/java/org/apache/baremaps/data/collection/MemoryAlignedDataMap.java
+++ b/baremaps-data/src/main/java/org/apache/baremaps/data/collection/MemoryAlignedDataMap.java
@@ -26,7 +26,8 @@ import org.apache.baremaps.data.memory.Memory;
import org.apache.baremaps.data.type.FixedSizeDataType;
/**
- * A {@link DataMap} that can hold a large number of fixed-size memory-aligned data elements.
+ * A map that stores fixed-size memory-aligned elements with optimized memory addressing.
+ * Uses bit-shift operations for fast memory access.
*
* <p>
* This code has been adapted from Planetiler (Apache license).
@@ -46,12 +47,73 @@ public class MemoryAlignedDataMap<E> implements DataMap<Long, E> {
private final long upperBoundary;
/**
- * Constructs a {@link MemoryAlignedDataMap}.
+ * Creates a new builder for a MemoryAlignedDataMap.
+ *
+ * @param <E> the type of values
+ * @return a new builder
+ */
+ public static <E> Builder<E> builder() {
+ return new Builder<>();
+ }
+
+ /**
+ * Builder for MemoryAlignedDataMap.
+ *
+ * @param <E> the type of values
+ */
+ public static class Builder<E> {
+ private FixedSizeDataType<E> dataType;
+ private Memory<?> memory;
+
+ /**
+ * Sets the data type for the map.
+ *
+ * @param dataType the data type
+ * @return this builder
+ */
+ public Builder<E> dataType(FixedSizeDataType<E> dataType) {
+ this.dataType = dataType;
+ return this;
+ }
+
+ /**
+ * Sets the memory for the map.
+ *
+ * @param memory the memory
+ * @return this builder
+ */
+ public Builder<E> memory(Memory<?> memory) {
+ this.memory = memory;
+ return this;
+ }
+
+ /**
+ * Builds a new MemoryAlignedDataMap.
+ *
+ * @return a new MemoryAlignedDataMap
+ * @throws IllegalStateException if required parameters are missing
+ */
+ public MemoryAlignedDataMap<E> build() {
+ if (dataType == null) {
+ throw new IllegalStateException("Data type must be specified");
+ }
+ if (memory == null) {
+ throw new IllegalStateException("Memory must be specified");
+ }
+
+ return new MemoryAlignedDataMap<>(dataType, memory);
+ }
+ }
+
+ /**
+ * Constructs a MemoryAlignedDataMap.
*
* @param dataType the data type
* @param memory the memory
+ * @throws DataCollectionException if memory and data type size requirements are not met
+ * @throws IllegalArgumentException if data type size is not a power of 2
*/
- public MemoryAlignedDataMap(FixedSizeDataType<E> dataType, Memory<?> memory) {
+ private MemoryAlignedDataMap(FixedSizeDataType<E> dataType, Memory<?> memory) {
if (dataType.size() > memory.segmentSize()) {
throw new DataCollectionException("The segment size is too small for the data type");
}
@@ -70,6 +132,13 @@ public class MemoryAlignedDataMap<E> implements DataMap<Long, E> {
: Long.MAX_VALUE >> (32 - segmentShift + valueShift);
}
+ /**
+ * Checks if the key is within valid boundaries.
+ *
+ * @param key the key to check
+ * @throws NullPointerException if key is null
+ * @throws IndexOutOfBoundsException if key is outside valid range
+ */
private void checkBoundary(Long key) {
Objects.requireNonNull(key, "Key couldn't be null");
if (key < 0 || key > upperBoundary) {
@@ -210,4 +279,12 @@ public class MemoryAlignedDataMap<E> implements DataMap<Long, E> {
};
}
+ @Override
+ public void close() throws Exception {
+ try {
+ memory.close();
+ } catch (Exception e) {
+ throw new DataCollectionException(e);
+ }
+ }
}
diff --git a/baremaps-data/src/main/java/org/apache/baremaps/data/collection/MonotonicDataMap.java b/baremaps-data/src/main/java/org/apache/baremaps/data/collection/MonotonicDataMap.java
index f590e815c..6d3621640 100644
--- a/baremaps-data/src/main/java/org/apache/baremaps/data/collection/MonotonicDataMap.java
+++ b/baremaps-data/src/main/java/org/apache/baremaps/data/collection/MonotonicDataMap.java
@@ -24,15 +24,11 @@ import org.apache.baremaps.data.type.PairDataType;
import org.apache.baremaps.data.type.PairDataType.Pair;
/**
- * A {@link DataMap} that can hold a large number of variable-size data elements. The elements must
- * be sorted by their key and inserted in a monotonic way. The elements cannot be removed or updated
- * once inserted.
+ * A map that stores values in a monotonically increasing key order. Optimized for
+ * sequential insertions and binary search lookups with chunked indexing.
*
* <p>
* This code has been adapted from Planetiler (Apache license).
- *
- * <p>
- * Copyright (c) Planetiler.
*/
public class MonotonicDataMap<E> implements DataMap<Long, E> {
@@ -41,40 +37,95 @@ public class MonotonicDataMap<E> implements DataMap<Long, E> {
private final AppendOnlyLog<E> values;
private long lastChunk = -1;
-
+
/**
- * Constructs a {@link MonotonicDataMap} with default lists for storing offsets.
+ * Creates a new builder for a MonotonicDataMap.
*
- * @param values the buffer of values
+ * @param <E> the type of values in the map
+ * @return a new builder
*/
- public MonotonicDataMap(AppendOnlyLog<E> values) {
- this(
- new MemoryAlignedDataList<>(new LongDataType()),
- new MemoryAlignedDataList<>(new PairDataType<>(new LongDataType(), new LongDataType())),
- values);
+ public static <E> Builder<E> builder() {
+ return new Builder<>();
}
-
+
/**
- * Constructs a {@link MonotonicDataMap} with default lists for storing offsets and keys.
+ * Builder for MonotonicDataMap.
*
- * @param keys the list of keys
- * @param values the buffer of values
+ * @param <E> the type of values in the map
*/
- public MonotonicDataMap(DataList<Pair<Long, Long>> keys, AppendOnlyLog<E> values) {
- this(
- new MemoryAlignedDataList<>(new LongDataType()),
- keys,
- values);
+ public static class Builder<E> {
+ private DataList<Long> offsets;
+ private DataList<Pair<Long, Long>> keys;
+ private AppendOnlyLog<E> values;
+
+ /**
+ * Sets the offsets list.
+ *
+ * @param offsets the list of offsets
+ * @return this builder
+ */
+ public Builder<E> offsets(DataList<Long> offsets) {
+ this.offsets = offsets;
+ return this;
+ }
+
+ /**
+ * Sets the keys list.
+ *
+ * @param keys the list of keys
+ * @return this builder
+ */
+ public Builder<E> keys(DataList<Pair<Long, Long>> keys) {
+ this.keys = keys;
+ return this;
+ }
+
+ /**
+ * Sets the values buffer.
+ *
+ * @param values the buffer of values
+ * @return this builder
+ */
+ public Builder<E> values(AppendOnlyLog<E> values) {
+ this.values = values;
+ return this;
+ }
+
+ /**
+ * Builds a new MonotonicDataMap.
+ *
+ * @return a new MonotonicDataMap
+ * @throws IllegalArgumentException if the values buffer is not provided
+ */
+ public MonotonicDataMap<E> build() {
+ if (values == null) {
+ throw new IllegalArgumentException("Values buffer must be provided");
+ }
+
+ if (offsets == null) {
+ offsets = MemoryAlignedDataList.<Long>builder()
+ .dataType(new LongDataType())
+ .build();
+ }
+
+ if (keys == null) {
+ keys = MemoryAlignedDataList.<Pair<Long, Long>>builder()
+ .dataType(new PairDataType<>(new LongDataType(), new LongDataType()))
+ .build();
+ }
+
+ return new MonotonicDataMap<>(offsets, keys, values);
+ }
}
/**
- * Constructs a {@link MonotonicDataMap}.
+ * Constructs a MonotonicDataMap.
*
* @param offsets the list of offsets
* @param keys the list of keys
* @param values the buffer of values
*/
- public MonotonicDataMap(DataList<Long> offsets, DataList<Pair<Long, Long>> keys,
+ private MonotonicDataMap(DataList<Long> offsets, DataList<Pair<Long, Long>> keys,
AppendOnlyLog<E> values) {
this.offsets = offsets;
this.keys = keys;
@@ -172,4 +223,15 @@ public class MonotonicDataMap<E> implements DataMap<Long, E> {
values.clear();
}
+ /** {@inheritDoc} */
+ @Override
+ public void close() throws Exception {
+ try {
+ offsets.close();
+ keys.close();
+ values.close();
+ } catch (Exception e) {
+ throw new DataCollectionException(e);
+ }
+ }
}
diff --git a/baremaps-data/src/main/java/org/apache/baremaps/data/collection/MonotonicFixedSizeDataMap.java b/baremaps-data/src/main/java/org/apache/baremaps/data/collection/MonotonicFixedSizeDataMap.java
index f0992cb94..a16b6f640 100644
--- a/baremaps-data/src/main/java/org/apache/baremaps/data/collection/MonotonicFixedSizeDataMap.java
+++ b/baremaps-data/src/main/java/org/apache/baremaps/data/collection/MonotonicFixedSizeDataMap.java
@@ -23,9 +23,8 @@ import java.util.Map.Entry;
import org.apache.baremaps.data.type.LongDataType;
/**
- * A {@link DataMap} that can hold a large number of fixed-size data elements. The elements must be
- * sorted by their key and inserted in a monotonic way. The elements cannot be removed or updated
- * once inserted.
+ * A map that stores fixed-size values in monotonically increasing key order.
+ * Optimized for sequential insertions and fast binary search lookups.
*
* <p>
* This code has been adapted from Planetiler (Apache license).
@@ -41,23 +40,93 @@ public class MonotonicFixedSizeDataMap<E> implements DataMap<Long, E> {
private long lastChunk = -1;
/**
- * Constructs a {@link MonotonicFixedSizeDataMap} with default lists for storing offsets and keys.
+ * Static factory method to create a new builder.
*
- * @param values the list of values
+ * @param <E> the type of elements
+ * @return a new builder
*/
- public MonotonicFixedSizeDataMap(DataList<E> values) {
- this(new MemoryAlignedDataList<>(new LongDataType()),
- new MemoryAlignedDataList<>(new LongDataType()), values);
+ public static <E> Builder<E> builder() {
+ return new Builder<>();
}
/**
- * Constructs a {@link MonotonicFixedSizeDataMap}.
+ * Builder for {@link MonotonicFixedSizeDataMap}.
+ *
+ * @param <E> the type of elements
+ */
+ public static class Builder<E> {
+ private DataList<Long> offsets;
+ private DataList<Long> keys;
+ private DataList<E> values;
+
+ /**
+ * Sets the offsets for the map.
+ *
+ * @param offsets the list of offsets
+ * @return this builder
+ */
+ public Builder<E> offsets(DataList<Long> offsets) {
+ this.offsets = offsets;
+ return this;
+ }
+
+ /**
+ * Sets the keys for the map.
+ *
+ * @param keys the list of keys
+ * @return this builder
+ */
+ public Builder<E> keys(DataList<Long> keys) {
+ this.keys = keys;
+ return this;
+ }
+
+ /**
+ * Sets the values for the map.
+ *
+ * @param values the list of values
+ * @return this builder
+ */
+ public Builder<E> values(DataList<E> values) {
+ this.values = values;
+ return this;
+ }
+
+ /**
+ * Builds a new {@link MonotonicFixedSizeDataMap}.
+ *
+ * @return a new MonotonicFixedSizeDataMap
+ * @throws IllegalStateException if values are missing
+ */
+ public MonotonicFixedSizeDataMap<E> build() {
+ if (values == null) {
+ throw new IllegalStateException("Values must be specified");
+ }
+
+ if (offsets == null) {
+ offsets = MemoryAlignedDataList.<Long>builder()
+ .dataType(new LongDataType())
+ .build();
+ }
+
+ if (keys == null) {
+ keys = MemoryAlignedDataList.<Long>builder()
+ .dataType(new LongDataType())
+ .build();
+ }
+
+ return new MonotonicFixedSizeDataMap<>(offsets, keys, values);
+ }
+ }
+
+ /**
+ * Private constructor for {@link MonotonicFixedSizeDataMap}.
*
* @param offsets the list of offsets
* @param keys the list of keys
* @param values the list of values
*/
- public MonotonicFixedSizeDataMap(
+ private MonotonicFixedSizeDataMap(
DataList<Long> offsets,
DataList<Long> keys,
DataList<E> values) {
@@ -152,4 +221,14 @@ public class MonotonicFixedSizeDataMap<E> implements DataMap<Long, E> {
values.clear();
}
+ @Override
+ public void close() throws Exception {
+ try {
+ offsets.close();
+ keys.close();
+ values.close();
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
}
diff --git a/baremaps-data/src/main/java/org/apache/baremaps/data/collection/MonotonicPairedDataMap.java b/baremaps-data/src/main/java/org/apache/baremaps/data/collection/MonotonicPairedDataMap.java
index ae64e0ddb..41fd57026 100644
--- a/baremaps-data/src/main/java/org/apache/baremaps/data/collection/MonotonicPairedDataMap.java
+++ b/baremaps-data/src/main/java/org/apache/baremaps/data/collection/MonotonicPairedDataMap.java
@@ -26,9 +26,8 @@ import org.apache.baremaps.data.type.LongDataType;
import org.apache.baremaps.data.type.PairDataType.Pair;
/**
- * A {@link DataMap} that can hold a large number of variable-size data elements. The elements must
- * be sorted by their key and inserted in a monotonic way. The elements cannot be removed or updated
- * once inserted.
+ * A map that stores values as key-value pairs in monotonically increasing key order. Optimized for
+ * sequential insertions and fast binary search lookups.
*
* <p>
* This code has been adapted from Planetiler (Apache license).
@@ -44,19 +43,74 @@ public class MonotonicPairedDataMap<E> implements DataMap<Long, E> {
private long lastChunk = -1;
/**
- * Constructs a {@link MonotonicPairedDataMap}.
+ * Creates a new builder for a MonotonicPairedDataMap.
+ *
+ * @param <E> the type of values
+ * @return a new builder
*/
- public MonotonicPairedDataMap(MemoryAlignedDataList<Pair<Long, E>> values) {
- this(new MemoryAlignedDataList<>(new LongDataType()), values);
+ public static <E> Builder<E> builder() {
+ return new Builder<>();
}
/**
- * Constructs a {@link MonotonicPairedDataMap}.
+ * Builder for MonotonicPairedDataMap.
+ *
+ * @param <E> the type of values
+ */
+ public static class Builder<E> {
+ private DataList<Long> offsets;
+ private MemoryAlignedDataList<Pair<Long, E>> values;
+
+ /**
+ * Sets the offsets for the map.
+ *
+ * @param offsets the list of offsets
+ * @return this builder
+ */
+ public Builder<E> offsets(DataList<Long> offsets) {
+ this.offsets = offsets;
+ return this;
+ }
+
+ /**
+ * Sets the values for the map.
+ *
+ * @param values the buffer of values
+ * @return this builder
+ */
+ public Builder<E> values(MemoryAlignedDataList<Pair<Long, E>> values) {
+ this.values = values;
+ return this;
+ }
+
+ /**
+ * Builds a new MonotonicPairedDataMap.
+ *
+ * @return a new MonotonicPairedDataMap
+ * @throws IllegalStateException if values are missing
+ */
+ public MonotonicPairedDataMap<E> build() {
+ if (values == null) {
+ throw new IllegalStateException("Values must be specified");
+ }
+
+ if (offsets == null) {
+ offsets = MemoryAlignedDataList.<Long>builder()
+ .dataType(new LongDataType())
+ .build();
+ }
+
+ return new MonotonicPairedDataMap<>(offsets, values);
+ }
+ }
+
+ /**
+ * Constructs a MonotonicPairedDataMap.
*
* @param offsets the list of offsets
* @param values the buffer of values
*/
- public MonotonicPairedDataMap(DataList<Long> offsets,
+ private MonotonicPairedDataMap(DataList<Long> offsets,
MemoryAlignedDataList<Pair<Long, E>> values) {
this.offsets = offsets;
this.values = values;
@@ -151,4 +205,14 @@ public class MonotonicPairedDataMap<E> implements DataMap<Long, E> {
offsets.clear();
values.clear();
}
+
+ @Override
+ public void close() throws Exception {
+ try {
+ offsets.close();
+ values.close();
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
}
diff --git a/baremaps-data/src/main/java/org/apache/baremaps/data/memory/Memory.java b/baremaps-data/src/main/java/org/apache/baremaps/data/memory/Memory.java
index d0a2580bf..56dd45a14 100644
--- a/baremaps-data/src/main/java/org/apache/baremaps/data/memory/Memory.java
+++ b/baremaps-data/src/main/java/org/apache/baremaps/data/memory/Memory.java
@@ -17,16 +17,13 @@
package org.apache.baremaps.data.memory;
-
-
-import java.io.Closeable;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.List;
-/** A base class to manage segments of on-heap, off-heap, or on-disk memory. */
-public abstract class Memory<T extends ByteBuffer> implements Closeable {
+/** A base class for managing on-heap, off-heap, or memory-mapped segments. */
+public abstract class Memory<T extends ByteBuffer> implements AutoCloseable {
private final int segmentSize;
@@ -36,10 +33,14 @@ public abstract class Memory<T extends ByteBuffer> implements Closeable {
protected final List<T> segments = new ArrayList<>();
+ // Flag to track if this Memory has been closed
+ protected volatile boolean closed = false;
+
/**
- * Constructs a memory with a given segment size.
+ * Constructs a memory with the specified segment size.
*
- * @param segmentSize the size of the segments
+ * @param segmentSize the size of the segments (must be a power of 2)
+ * @throws IllegalArgumentException if the segment size is not a power of 2
*/
protected Memory(int segmentSize) {
if ((segmentSize & -segmentSize) != segmentSize) {
@@ -51,37 +52,38 @@ public abstract class Memory<T extends ByteBuffer> implements Closeable {
}
/**
- * Returns the size of the segments.
+ * Returns the size of each segment.
*
- * @return the size of the segments
+ * @return the segment size in bytes
*/
public int segmentSize() {
return segmentSize;
}
/**
- * Returns the bit shift to find a segment index from a memory position.
+ * Returns the bit shift used to find a segment index from a memory position.
*
- * @return the bit shift
+ * @return the bit shift value
*/
public long segmentShift() {
return segmentShift;
}
/**
- * Returns the bit mask to find a segment offset from a memory position.
+ * Returns the bit mask used to find an offset within a segment from a memory position.
*
- * @return the bit mask
+ * @return the bit mask value
*/
public long segmentMask() {
return segmentMask;
}
/**
- * Returns a segment of the memory.
+ * Returns a segment at the specified index, allocating it if necessary.
*
- * @param index the index of the segment
- * @return the segment
+ * @param index the segment index
+ * @return the segment as a ByteBuffer
+ * @throws MemoryException if segment allocation fails
*/
public ByteBuffer segment(int index) {
if (segments.size() <= index) {
@@ -94,38 +96,82 @@ public abstract class Memory<T extends ByteBuffer> implements Closeable {
return segment;
}
- /** The allocation of segments is synchronized to enable access by multiple threads. */
- private synchronized ByteBuffer allocate(int index) {
- while (segments.size() <= index) {
- segments.add(null);
+ /**
+ * Checks if this Memory has been closed.
+ *
+ * @throws IllegalStateException if this Memory has been closed
+ */
+ protected void checkNotClosed() {
+ if (closed) {
+ throw new IllegalStateException("Memory has been closed");
}
- T segment = segments.get(index);
- if (segment == null) {
- segment = allocate(index, segmentSize);
- segments.set(index, segment);
+ }
+
+ /**
+ * Allocates a segment at the specified index. Thread-safe method.
+ *
+ * @param index the segment index
+ * @return the allocated segment
+ * @throws MemoryException if allocation fails
+ */
+ private synchronized ByteBuffer allocate(int index) {
+ checkNotClosed();
+
+ try {
+ while (segments.size() <= index) {
+ segments.add(null);
+ }
+ T segment = segments.get(index);
+ if (segment == null) {
+ segment = allocate(index, segmentSize);
+ segments.set(index, segment);
+ }
+ return segment;
+ } catch (OutOfMemoryError e) {
+ throw new MemoryException(
+ "Failed to allocate memory segment of size " + segmentSize + " bytes", e);
+ } catch (Exception e) {
+ throw new MemoryException("Failed to allocate memory segment", e);
}
- return segment;
}
- /** Returns the size of the allocated memory. */
+ /**
+ * Returns the total size of allocated memory.
+ *
+ * @return the size in bytes
+ */
public long size() {
+ checkNotClosed();
return (long) segments.size() * (long) segmentSize;
}
/**
- * Allocates a segment for a given index and size.
+ * Allocates a segment of the specified size.
*
- * @param index the index of the segment
- * @param size the size of the segment
- * @return the segment
+ * @param index the segment index
+ * @param size the segment size in bytes
+ * @return the allocated segment
*/
protected abstract T allocate(int index, int size);
/**
- * Clears the memory and the underlying resources.
+ * Releases resources associated with this memory. Unlike {@link #clear()}, this method does not
+ * delete underlying data.
+ *
+ * @throws IOException if an I/O error occurs
*/
- public abstract void clear() throws IOException;
-
-
+ @Override
+ public synchronized void close() throws IOException {
+ if (!closed) {
+ closed = true;
+ }
+ }
+ /**
+ * Deletes all data managed by this memory. Unlike {@link #close()}, this method removes
+ * underlying data.
+ *
+ * @throws IOException if an I/O error occurs
+ */
+ public abstract void clear() throws IOException;
}
diff --git a/baremaps-data/src/main/java/org/apache/baremaps/data/memory/MemoryException.java b/baremaps-data/src/main/java/org/apache/baremaps/data/memory/MemoryException.java
index 3a4cbb6e0..e261269f2 100644
--- a/baremaps-data/src/main/java/org/apache/baremaps/data/memory/MemoryException.java
+++ b/baremaps-data/src/main/java/org/apache/baremaps/data/memory/MemoryException.java
@@ -17,35 +17,35 @@
package org.apache.baremaps.data.memory;
-/** Signals that an exception occurred in a memory. */
+/** Exception thrown when a memory operation fails. */
public class MemoryException extends RuntimeException {
- /** Constructs a {@link MemoryException} with {@code null} as its error detail message. */
+ /** Constructs a MemoryException with no message or cause. */
public MemoryException() {}
/**
- * Constructs an {@link MemoryException} with the specified detail message.
+ * Constructs a MemoryException with the specified message.
*
- * @param message the message
+ * @param message error message
*/
public MemoryException(String message) {
super(message);
}
/**
- * Constructs a {@link MemoryException} with the specified cause.
+ * Constructs a MemoryException with the specified cause.
*
- * @param cause the cause
+ * @param cause the underlying cause
*/
public MemoryException(Throwable cause) {
super(cause);
}
/**
- * Constructs a {@link MemoryException} with the specified detail message and cause.
+ * Constructs a MemoryException with the specified message and cause.
*
- * @param message the message
- * @param cause the cause
+ * @param message error message
+ * @param cause the underlying cause
*/
public MemoryException(String message, Throwable cause) {
super(message, cause);
diff --git a/baremaps-data/src/main/java/org/apache/baremaps/data/memory/MemoryMappedDirectory.java b/baremaps-data/src/main/java/org/apache/baremaps/data/memory/MemoryMappedDirectory.java
index 82d2e0af7..d00e3a90a 100644
--- a/baremaps-data/src/main/java/org/apache/baremaps/data/memory/MemoryMappedDirectory.java
+++ b/baremaps-data/src/main/java/org/apache/baremaps/data/memory/MemoryMappedDirectory.java
@@ -17,8 +17,6 @@
package org.apache.baremaps.data.memory;
-
-
import java.io.IOException;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
@@ -29,28 +27,25 @@ import org.apache.baremaps.data.util.FileUtils;
import org.apache.baremaps.data.util.MappedByteBufferUtils;
-/**
- * A {@link Memory} that stores segments on-disk using mapped byte buffers in a directory of files.
- */
+/** Memory implementation that uses memory-mapped files in a directory for storage. */
public class MemoryMappedDirectory extends Memory<MappedByteBuffer> {
private final Path directory;
/**
- * Constructs an {@link MemoryMappedDirectory} with a custom directory and a default segment size
- * of 1gb.
+ * Constructs a MemoryMappedDirectory with the specified directory and 1GB segment size.
*
- * @param directory the directory that stores the data
+ * @param directory the directory to store segments in
*/
public MemoryMappedDirectory(Path directory) {
this(directory, 1 << 30);
}
/**
- * Constructs an {@link MemoryMappedDirectory} with a custom directory and a custom segment size.
+ * Constructs a MemoryMappedDirectory with the specified directory and segment size.
*
- * @param directory the directory that stores the data
- * @param segmentBytes the size of the segments in bytes
+ * @param directory the directory to store segments in
+ * @param segmentBytes the size of each segment in bytes
*/
public MemoryMappedDirectory(Path directory, int segmentBytes) {
super(segmentBytes);
@@ -71,20 +66,35 @@ public class MemoryMappedDirectory extends Memory<MappedByteBuffer> {
}
}
- /** {@inheritDoc} */
+ /**
+ * Releases all mapped buffers but keeps the files intact.
+ *
+ * {@inheritDoc}
+ */
@Override
- public void close() throws IOException {
+ public synchronized void close() throws IOException {
+ // Release MappedByteBuffer resources
for (MappedByteBuffer buffer : segments) {
- MappedByteBufferUtils.unmap(buffer);
+ if (buffer != null) {
+ MappedByteBufferUtils.unmap(buffer);
+ }
}
}
- /** {@inheritDoc} */
+ /**
+ * Unmaps all buffers and deletes the directory with all its files.
+ *
+ * {@inheritDoc}
+ */
@Override
- public void clear() throws IOException {
+ public synchronized void clear() throws IOException {
+ // Release resources first
close();
+
+ // Clear the segment list
segments.clear();
+
+ // Delete the directory and all files in it
FileUtils.deleteRecursively(directory);
}
-
}
diff --git a/baremaps-data/src/main/java/org/apache/baremaps/data/memory/MemoryMappedFile.java b/baremaps-data/src/main/java/org/apache/baremaps/data/memory/MemoryMappedFile.java
index 5db613d34..54a9ddeb0 100644
--- a/baremaps-data/src/main/java/org/apache/baremaps/data/memory/MemoryMappedFile.java
+++ b/baremaps-data/src/main/java/org/apache/baremaps/data/memory/MemoryMappedFile.java
@@ -17,8 +17,6 @@
package org.apache.baremaps.data.memory;
-
-
import java.io.IOException;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
@@ -28,25 +26,25 @@ import java.nio.file.Path;
import java.nio.file.StandardOpenOption;
import org.apache.baremaps.data.util.MappedByteBufferUtils;
-/** A {@link Memory} that stores segments on-disk using mapped byte buffers in a file. */
+/** Memory implementation that uses memory-mapped file for storage. */
public class MemoryMappedFile extends Memory<MappedByteBuffer> {
private final Path file;
/**
- * Constructs an {@link MemoryMappedFile} with a custom file and a default segment size of 1gb.
+ * Constructs a MemoryMappedFile with the specified file and 1GB segment size.
*
- * @param file the file that stores the data
+ * @param file the file to memory-map
*/
public MemoryMappedFile(Path file) {
this(file, 1 << 30);
}
/**
- * Constructs an {@link MemoryMappedFile} with a custom file and a custom segment size.
+ * Constructs a MemoryMappedFile with the specified file and segment size.
*
- * @param file the file that stores the data
- * @param segmentBytes the size of the segments in bytes
+ * @param file the file to memory-map
+ * @param segmentBytes the size of each segment in bytes
*/
public MemoryMappedFile(Path file, int segmentBytes) {
super(segmentBytes);
@@ -66,19 +64,35 @@ public class MemoryMappedFile extends Memory<MappedByteBuffer> {
}
}
- /** {@inheritDoc} */
+ /**
+ * Releases all mapped buffers but keeps the file intact.
+ *
+ * {@inheritDoc}
+ */
@Override
- public void close() throws IOException {
+ public synchronized void close() throws IOException {
+ // Release MappedByteBuffer resources
for (MappedByteBuffer buffer : segments) {
- MappedByteBufferUtils.unmap(buffer);
+ if (buffer != null) {
+ MappedByteBufferUtils.unmap(buffer);
+ }
}
}
- /** {@inheritDoc} */
+ /**
+ * Unmaps all buffers and deletes the file.
+ *
+ * {@inheritDoc}
+ */
@Override
- public void clear() throws IOException {
+ public synchronized void clear() throws IOException {
+ // Release resources first
close();
+
+ // Clear the segment list
segments.clear();
- Files.delete(file);
+
+ // Delete the file
+ Files.deleteIfExists(file);
}
}
diff --git a/baremaps-data/src/main/java/org/apache/baremaps/data/memory/OffHeapMemory.java b/baremaps-data/src/main/java/org/apache/baremaps/data/memory/OffHeapMemory.java
index f95f03b51..66a2b7f2e 100644
--- a/baremaps-data/src/main/java/org/apache/baremaps/data/memory/OffHeapMemory.java
+++ b/baremaps-data/src/main/java/org/apache/baremaps/data/memory/OffHeapMemory.java
@@ -17,23 +17,21 @@
package org.apache.baremaps.data.memory;
-
-
import java.io.IOException;
import java.nio.ByteBuffer;
-/** A {@link Memory} that stores segments off-heap using direct byte buffers. */
+/** Memory implementation that uses off-heap (direct) byte buffers for storage. */
public class OffHeapMemory extends Memory<ByteBuffer> {
- /** Constructs an {@link OffHeapMemory} with a default segment size of 1mb. */
+ /** Constructs an OffHeapMemory with a 1MB default segment size. */
public OffHeapMemory() {
this(1 << 20);
}
/**
- * Constructs an {@link OffHeapMemory} with a custom segment size.
+ * Constructs an OffHeapMemory with the specified segment size.
*
- * @param segmentSize the size of the segments in bytes
+ * @param segmentSize the size of each segment in bytes
*/
public OffHeapMemory(int segmentSize) {
super(segmentSize);
@@ -45,15 +43,25 @@ public class OffHeapMemory extends Memory<ByteBuffer> {
return ByteBuffer.allocateDirect(size);
}
- /** {@inheritDoc} */
+ /**
+ * Direct buffers are managed by GC and can't be explicitly freed in Java 8.
+ *
+ * {@inheritDoc}
+ */
@Override
- public void close() throws IOException {
- // Nothing to close
+ public synchronized void close() throws IOException {
+ // Direct ByteBuffers are managed by GC - we can't explicitly free them in Java 8
+ // In Java 9+, we could use Cleaner or Unsafe API if needed
}
- /** {@inheritDoc} */
+ /**
+ * Clears all segments to allow garbage collection.
+ *
+ * {@inheritDoc}
+ */
@Override
- public void clear() throws IOException {
- // Nothing to clean
+ public synchronized void clear() throws IOException {
+ // Clear the segment list to allow GC to reclaim the memory
+ segments.clear();
}
}
diff --git a/baremaps-data/src/main/java/org/apache/baremaps/data/memory/OnHeapMemory.java b/baremaps-data/src/main/java/org/apache/baremaps/data/memory/OnHeapMemory.java
index 4b0fff757..d0be3968e 100644
--- a/baremaps-data/src/main/java/org/apache/baremaps/data/memory/OnHeapMemory.java
+++ b/baremaps-data/src/main/java/org/apache/baremaps/data/memory/OnHeapMemory.java
@@ -17,23 +17,21 @@
package org.apache.baremaps.data.memory;
-
-
import java.io.IOException;
import java.nio.ByteBuffer;
-/** A {@link Memory} that stores segments on-heap using regular byte buffers. */
+/** Memory implementation that uses on-heap byte buffers for storage. */
public class OnHeapMemory extends Memory<ByteBuffer> {
- /** Constructs an {@link OnHeapMemory} with a default segment size of 1mb. */
+ /** Constructs an OnHeapMemory with a 1MB default segment size. */
public OnHeapMemory() {
this(1 << 20);
}
/**
- * Constructs an {@link OnHeapMemory} with a custom segment size.
+ * Constructs an OnHeapMemory with the specified segment size.
*
- * @param segmentSize the size of the segments in bytes
+ * @param segmentSize the size of each segment in bytes
*/
public OnHeapMemory(int segmentSize) {
super(segmentSize);
@@ -45,15 +43,24 @@ public class OnHeapMemory extends Memory<ByteBuffer> {
return ByteBuffer.allocate(size);
}
- /** {@inheritDoc} */
+ /**
+ * On-heap buffers don't require explicit cleanup.
+ *
+ * {@inheritDoc}
+ */
@Override
- public void close() throws IOException {
- // Nothing to close
+ public synchronized void close() throws IOException {
+ // On-heap ByteBuffers don't need special cleanup
}
- /** {@inheritDoc} */
+ /**
+ * Clears all segments to allow garbage collection.
+ *
+ * {@inheritDoc}
+ */
@Override
- public void clear() throws IOException {
- // Nothing to clean
+ public synchronized void clear() throws IOException {
+ // Clear the segment list to allow GC to reclaim the memory
+ segments.clear();
}
}
diff --git a/baremaps-data/src/main/java/org/apache/baremaps/data/type/BooleanArrayDataType.java b/baremaps-data/src/main/java/org/apache/baremaps/data/type/BooleanArrayDataType.java
index 328a483e0..628eaf413 100644
--- a/baremaps-data/src/main/java/org/apache/baremaps/data/type/BooleanArrayDataType.java
+++ b/baremaps-data/src/main/java/org/apache/baremaps/data/type/BooleanArrayDataType.java
@@ -21,7 +21,9 @@ package org.apache.baremaps.data.type;
import java.nio.ByteBuffer;
-/** A {@link DataType} for reading and writing lists of floats in {@link ByteBuffer}s. */
+/**
+ * A {@link DataType} for reading and writing arrays of boolean values in {@link ByteBuffer}s.
+ */
public class BooleanArrayDataType implements DataType<boolean[]> {
/** {@inheritDoc} */
diff --git a/baremaps-data/src/main/java/org/apache/baremaps/data/type/BooleanDataType.java b/baremaps-data/src/main/java/org/apache/baremaps/data/type/BooleanDataType.java
index 5758aad52..65e286c45 100644
--- a/baremaps-data/src/main/java/org/apache/baremaps/data/type/BooleanDataType.java
+++ b/baremaps-data/src/main/java/org/apache/baremaps/data/type/BooleanDataType.java
@@ -23,10 +23,14 @@ import static java.lang.Boolean.TRUE;
import java.nio.ByteBuffer;
-/** A {@link DataType} for reading and writing bytes in {@link ByteBuffer}s. */
+/**
+ * A {@link DataType} for reading and writing boolean values in {@link ByteBuffer}s.
+ */
public class BooleanDataType extends MemoryAlignedDataType<Boolean> {
- /** Constructs a {@link ByteDataType}. */
+ /**
+ * Constructs a {@link BooleanDataType} with a fixed size of {@link Byte#BYTES}.
+ */
public BooleanDataType() {
super(Byte.BYTES);
}
diff --git a/baremaps-data/src/main/java/org/apache/baremaps/data/type/BooleanListDataType.java b/baremaps-data/src/main/java/org/apache/baremaps/data/type/BooleanListDataType.java
index 0368a67a1..b9395c29e 100644
--- a/baremaps-data/src/main/java/org/apache/baremaps/data/type/BooleanListDataType.java
+++ b/baremaps-data/src/main/java/org/apache/baremaps/data/type/BooleanListDataType.java
@@ -23,7 +23,9 @@ import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.List;
-/** A {@link DataType} for reading and writing lists of floats in {@link ByteBuffer}s. */
+/**
+ * A {@link DataType} for reading and writing lists of boolean values in {@link ByteBuffer}s.
+ */
public class BooleanListDataType implements DataType<List<Boolean>> {
/** {@inheritDoc} */
diff --git a/baremaps-data/src/main/java/org/apache/baremaps/data/type/ByteArrayDataType.java b/baremaps-data/src/main/java/org/apache/baremaps/data/type/ByteArrayDataType.java
index c1210dcb1..787f4bb42 100644
--- a/baremaps-data/src/main/java/org/apache/baremaps/data/type/ByteArrayDataType.java
+++ b/baremaps-data/src/main/java/org/apache/baremaps/data/type/ByteArrayDataType.java
@@ -21,7 +21,7 @@ package org.apache.baremaps.data.type;
import java.nio.ByteBuffer;
/**
- * A {@link DataType} for reading and writing lists of values in {@link ByteBuffer}s.
+ * A {@link DataType} for reading and writing byte arrays in {@link ByteBuffer}s.
*/
public class ByteArrayDataType implements DataType<byte[]> {
diff --git a/baremaps-data/src/main/java/org/apache/baremaps/data/type/ByteDataType.java b/baremaps-data/src/main/java/org/apache/baremaps/data/type/ByteDataType.java
index 1c14bd945..b1899ec07 100644
--- a/baremaps-data/src/main/java/org/apache/baremaps/data/type/ByteDataType.java
+++ b/baremaps-data/src/main/java/org/apache/baremaps/data/type/ByteDataType.java
@@ -17,14 +17,16 @@
package org.apache.baremaps.data.type;
-
-
import java.nio.ByteBuffer;
-/** A {@link DataType} for reading and writing bytes in {@link ByteBuffer}s. */
+/**
+ * A {@link DataType} for reading and writing byte values in {@link ByteBuffer}s.
+ */
public class ByteDataType extends MemoryAlignedDataType<Byte> {
- /** Constructs a {@link ByteDataType}. */
+ /**
+ * Constructs a {@link ByteDataType} with a fixed size of {@link Byte#BYTES}.
+ */
public ByteDataType() {
super(Byte.BYTES);
}
diff --git a/baremaps-data/src/main/java/org/apache/baremaps/data/type/ByteListDataType.java b/baremaps-data/src/main/java/org/apache/baremaps/data/type/ByteListDataType.java
index 8ed14b208..41248ccd2 100644
--- a/baremaps-data/src/main/java/org/apache/baremaps/data/type/ByteListDataType.java
+++ b/baremaps-data/src/main/java/org/apache/baremaps/data/type/ByteListDataType.java
@@ -24,7 +24,7 @@ import java.nio.ByteBuffer;
import java.util.List;
/**
- * A {@link DataType} for reading and writing lists of bytes in {@link ByteBuffer}s.
+ * A {@link DataType} for reading and writing lists of byte values in {@link ByteBuffer}s.
*/
public class ByteListDataType implements DataType<List<Byte>> {
diff --git a/baremaps-data/src/main/java/org/apache/baremaps/data/type/CoordinateArrayDataType.java b/baremaps-data/src/main/java/org/apache/baremaps/data/type/CoordinateArrayDataType.java
index 124dc1e99..c339b78c5 100644
--- a/baremaps-data/src/main/java/org/apache/baremaps/data/type/CoordinateArrayDataType.java
+++ b/baremaps-data/src/main/java/org/apache/baremaps/data/type/CoordinateArrayDataType.java
@@ -21,7 +21,8 @@ import java.nio.ByteBuffer;
import org.locationtech.jts.geom.Coordinate;
/**
- * A data type for {@link Coordinate} arrays.
+ * A {@link DataType} for reading and writing arrays of {@link Coordinate} values in
+ * {@link ByteBuffer}s.
*/
public class CoordinateArrayDataType implements DataType<Coordinate[]> {
diff --git a/baremaps-data/src/main/java/org/apache/baremaps/data/type/CoordinateDataType.java b/baremaps-data/src/main/java/org/apache/baremaps/data/type/CoordinateDataType.java
index 0e4d99961..4d659af2c 100644
--- a/baremaps-data/src/main/java/org/apache/baremaps/data/type/CoordinateDataType.java
+++ b/baremaps-data/src/main/java/org/apache/baremaps/data/type/CoordinateDataType.java
@@ -22,10 +22,12 @@ package org.apache.baremaps.data.type;
import java.nio.ByteBuffer;
import org.locationtech.jts.geom.Coordinate;
-/** A {@link DataType} for reading and writing {@link Coordinate}s in {@link ByteBuffer}s. */
+/** A {@link DataType} for reading and writing {@link Coordinate} values in {@link ByteBuffer}s. */
public class CoordinateDataType extends MemoryAlignedDataType<Coordinate> {
- /** Constructs a {@link CoordinateDataType}. */
+ /**
+ * Constructs a {@link CoordinateDataType} with a fixed size of two {@link Double#BYTES}.
+ */
public CoordinateDataType() {
super(Double.BYTES * 2);
}
diff --git a/baremaps-data/src/main/java/org/apache/baremaps/data/type/DataType.java b/baremaps-data/src/main/java/org/apache/baremaps/data/type/DataType.java
index 281cc794b..26f9901b1 100644
--- a/baremaps-data/src/main/java/org/apache/baremaps/data/type/DataType.java
+++ b/baremaps-data/src/main/java/org/apache/baremaps/data/type/DataType.java
@@ -25,7 +25,7 @@ import java.nio.ByteBuffer;
* A data type for reading and writing values in {@link ByteBuffer}s. Read and write operations must
* use absolute positions within the {@link ByteBuffer}.
*
- * @param <T>
+ * @param <T> the type of value being read or written
*/
public interface DataType<T> {
@@ -33,34 +33,34 @@ public interface DataType<T> {
* Returns the size of the value.
*
* @param value the value
- * @return the size of the value
+ * @return the size of the value in bytes
*/
int size(final T value);
/**
* Returns the size of the value stored at the specified position in a {@link ByteBuffer}.
*
- * @param buffer the buffer
- * @param position the position
- * @return the size of the value
+ * @param buffer the buffer containing the value
+ * @param position the absolute position of the value within the buffer
+ * @return the size of the value in bytes
*/
int size(final ByteBuffer buffer, final int position);
/**
- * Write a value.
+ * Writes a value to the specified position in a {@link ByteBuffer}.
*
- * @param buffer the source buffer
- * @param position the absolute position of the value within the buffer
- * @param value the value
+ * @param buffer the destination buffer
+ * @param position the absolute position within the buffer to write the value
+ * @param value the value to write
*/
void write(final ByteBuffer buffer, final int position, final T value);
/**
- * Read a value.
+ * Reads a value from the specified position in a {@link ByteBuffer}.
*
* @param buffer the source buffer
- * @param position the absolute position of the value within the buffer
- * @return the object
+ * @param position the absolute position within the buffer to read the value
+ * @return the read value
*/
T read(final ByteBuffer buffer, final int position);
}
diff --git a/baremaps-data/src/main/java/org/apache/baremaps/data/type/DoubleArrayDataType.java b/baremaps-data/src/main/java/org/apache/baremaps/data/type/DoubleArrayDataType.java
index ecd83f681..cb2ce175c 100644
--- a/baremaps-data/src/main/java/org/apache/baremaps/data/type/DoubleArrayDataType.java
+++ b/baremaps-data/src/main/java/org/apache/baremaps/data/type/DoubleArrayDataType.java
@@ -17,11 +17,11 @@
package org.apache.baremaps.data.type;
-
-
import java.nio.ByteBuffer;
-/** A {@link DataType} for reading and writing lists of doubles in {@link ByteBuffer}s. */
+/**
+ * A {@link DataType} for reading and writing arrays of double values in {@link ByteBuffer}s.
+ */
public class DoubleArrayDataType implements DataType<double[]> {
/** {@inheritDoc} */
diff --git a/baremaps-data/src/main/java/org/apache/baremaps/data/type/DoubleDataType.java b/baremaps-data/src/main/java/org/apache/baremaps/data/type/DoubleDataType.java
index 030b36c63..9a40116da 100644
--- a/baremaps-data/src/main/java/org/apache/baremaps/data/type/DoubleDataType.java
+++ b/baremaps-data/src/main/java/org/apache/baremaps/data/type/DoubleDataType.java
@@ -17,14 +17,16 @@
package org.apache.baremaps.data.type;
-
-
import java.nio.ByteBuffer;
-/** A {@link DataType} for reading and writing doubles in {@link ByteBuffer}s. */
+/**
+ * A {@link DataType} for reading and writing double values in {@link ByteBuffer}s.
+ */
public class DoubleDataType extends MemoryAlignedDataType<Double> {
- /** Constructs a {@link DoubleDataType}. */
+ /**
+ * Constructs a {@link DoubleDataType} with a fixed size of {@link Double#BYTES}.
+ */
public DoubleDataType() {
super(Double.BYTES);
}
diff --git a/baremaps-data/src/main/java/org/apache/baremaps/data/type/DoubleListDataType.java b/baremaps-data/src/main/java/org/apache/baremaps/data/type/DoubleListDataType.java
index 16e1133d6..5d2e8fa6f 100644
--- a/baremaps-data/src/main/java/org/apache/baremaps/data/type/DoubleListDataType.java
+++ b/baremaps-data/src/main/java/org/apache/baremaps/data/type/DoubleListDataType.java
@@ -17,13 +17,13 @@
package org.apache.baremaps.data.type;
-
-
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.List;
-/** A {@link DataType} for reading and writing lists of doubles in {@link ByteBuffer}s. */
+/**
+ * A {@link DataType} for reading and writing lists of double values in {@link ByteBuffer}s.
+ */
public class DoubleListDataType implements DataType<List<Double>> {
/** {@inheritDoc} */
diff --git a/baremaps-data/src/main/java/org/apache/baremaps/data/type/FixedSizeDataType.java b/baremaps-data/src/main/java/org/apache/baremaps/data/type/FixedSizeDataType.java
index 04a51bcfd..f62cb427b 100644
--- a/baremaps-data/src/main/java/org/apache/baremaps/data/type/FixedSizeDataType.java
+++ b/baremaps-data/src/main/java/org/apache/baremaps/data/type/FixedSizeDataType.java
@@ -24,7 +24,7 @@ import java.nio.ByteBuffer;
/**
* A {@link DataType} for reading and writing values in {@link ByteBuffer}s whose size is fixed.
*
- * @param <T>
+ * @param <T> the type of value being read or written
*/
public abstract class FixedSizeDataType<T> implements DataType<T> {
@@ -33,7 +33,7 @@ public abstract class FixedSizeDataType<T> implements DataType<T> {
/**
* Creates a {@link FixedSizeDataType} with a fixed size.
*
- * @param size the size of the value
+ * @param size the size of the value in bytes
*/
protected FixedSizeDataType(final int size) {
this.size = size;
@@ -52,9 +52,9 @@ public abstract class FixedSizeDataType<T> implements DataType<T> {
}
/**
- * Returns the size of the data type.
+ * Returns the fixed size of this data type.
*
- * @return the size of the data type
+ * @return the size in bytes
*/
public int size() {
return size;
diff --git a/baremaps-data/src/main/java/org/apache/baremaps/data/type/FloatArrayDataType.java b/baremaps-data/src/main/java/org/apache/baremaps/data/type/FloatArrayDataType.java
index a970f8f0d..4f0b303c2 100644
--- a/baremaps-data/src/main/java/org/apache/baremaps/data/type/FloatArrayDataType.java
+++ b/baremaps-data/src/main/java/org/apache/baremaps/data/type/FloatArrayDataType.java
@@ -17,11 +17,11 @@
package org.apache.baremaps.data.type;
-
-
import java.nio.ByteBuffer;
-/** A {@link DataType} for reading and writing lists of floats in {@link ByteBuffer}s. */
+/**
+ * A {@link DataType} for reading and writing arrays of float values in {@link ByteBuffer}s.
+ */
public class FloatArrayDataType implements DataType<float[]> {
/** {@inheritDoc} */
diff --git a/baremaps-data/src/main/java/org/apache/baremaps/data/type/FloatDataType.java b/baremaps-data/src/main/java/org/apache/baremaps/data/type/FloatDataType.java
index 660a21bd5..8eca4fa10 100644
--- a/baremaps-data/src/main/java/org/apache/baremaps/data/type/FloatDataType.java
+++ b/baremaps-data/src/main/java/org/apache/baremaps/data/type/FloatDataType.java
@@ -22,11 +22,13 @@ package org.apache.baremaps.data.type;
import java.nio.ByteBuffer;
/**
- * A {@link DataType} for reading and writing floats in {@link ByteBuffer}s.
+ * A {@link DataType} for reading and writing float values in {@link ByteBuffer}s.
*/
public class FloatDataType extends MemoryAlignedDataType<Float> {
- /** Constructs a {@link FloatDataType}. */
+ /**
+ * Constructs a {@link FloatDataType} with a fixed size of {@link Float#BYTES}.
+ */
public FloatDataType() {
super(Float.BYTES);
}
diff --git a/baremaps-data/src/main/java/org/apache/baremaps/data/type/FloatListDataType.java b/baremaps-data/src/main/java/org/apache/baremaps/data/type/FloatListDataType.java
index 3f11fc5ba..e25e5f66e 100644
--- a/baremaps-data/src/main/java/org/apache/baremaps/data/type/FloatListDataType.java
+++ b/baremaps-data/src/main/java/org/apache/baremaps/data/type/FloatListDataType.java
@@ -17,13 +17,13 @@
package org.apache.baremaps.data.type;
-
-
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.List;
-/** A {@link DataType} for reading and writing lists of floats in {@link ByteBuffer}s. */
+/**
+ * A {@link DataType} for reading and writing lists of float values in {@link ByteBuffer}s.
+ */
public class FloatListDataType implements DataType<List<Float>> {
/** {@inheritDoc} */
diff --git a/baremaps-data/src/main/java/org/apache/baremaps/data/type/GeometryCollectionDataType.java b/baremaps-data/src/main/java/org/apache/baremaps/data/type/GeometryCollectionDataType.java
index 768a27b67..814ad6807 100644
--- a/baremaps-data/src/main/java/org/apache/baremaps/data/type/GeometryCollectionDataType.java
+++ b/baremaps-data/src/main/java/org/apache/baremaps/data/type/GeometryCollectionDataType.java
@@ -24,7 +24,8 @@ import org.locationtech.jts.geom.GeometryCollection;
import org.locationtech.jts.geom.GeometryFactory;
/**
- * A data type for {@link GeometryCollection} objects.
+ * A {@link DataType} for reading and writing {@link GeometryCollection} objects in
+ * {@link ByteBuffer}s.
*/
public class GeometryCollectionDataType implements DataType<GeometryCollection> {
@@ -33,14 +34,14 @@ public class GeometryCollectionDataType implements DataType<GeometryCollection>
private final GeometryDataType geometryDataType;
/**
- * Constructs a {@code GeometryCollectionDataType} with a default {@code GeometryFactory}.
+ * Constructs a {@link GeometryCollectionDataType} with a default {@link GeometryFactory}.
*/
public GeometryCollectionDataType() {
this(new GeometryFactory(), new GeometryDataType());
}
/**
- * Constructs a {@code GeometryCollectionDataType} with a specified {@code GeometryFactory}.
+ * Constructs a {@link GeometryCollectionDataType} with a specified {@link GeometryFactory}.
*
* @param geometryFactory the geometry factory
*/
@@ -49,8 +50,8 @@ public class GeometryCollectionDataType implements DataType<GeometryCollection>
}
/**
- * Constructs a {@code GeometryCollectionDataType} with a specified {@code GeometryFactory} and
- * {@code GeometryDataType}.
+ * Constructs a {@link GeometryCollectionDataType} with a specified {@link GeometryFactory} and
+ * {@link GeometryDataType}.
*
* @param geometryFactory the geometry factory
* @param geometryDataType the geometry data type
diff --git a/baremaps-data/src/main/java/org/apache/baremaps/data/type/GeometryDataType.java b/baremaps-data/src/main/java/org/apache/baremaps/data/type/GeometryDataType.java
index 8e741d007..c124ff091 100644
--- a/baremaps-data/src/main/java/org/apache/baremaps/data/type/GeometryDataType.java
+++ b/baremaps-data/src/main/java/org/apache/baremaps/data/type/GeometryDataType.java
@@ -22,7 +22,7 @@ import java.nio.ByteBuffer;
import org.locationtech.jts.geom.*;
/**
- * A {@code DataType} for {@link Geometry} objects.
+ * A {@link DataType} for reading and writing {@link Geometry} objects in {@link ByteBuffer}s.
*/
public class GeometryDataType implements DataType<Geometry> {
@@ -42,16 +42,16 @@ public class GeometryDataType implements DataType<Geometry> {
private final GeometryCollectionDataType geometryCollectionDataType;
/**
- * Constructs a {@code GeometryDataType} with a default {@code GeometryFactory}.
+ * Constructs a {@link GeometryDataType} with a default {@link GeometryFactory}.
*/
public GeometryDataType() {
this(new GeometryFactory());
}
/**
- * Constructs a {@code GeometryDataType} with a specified {@code GeometryFactory}.
+ * Constructs a {@link GeometryDataType} with a specified {@link GeometryFactory}.
*
- * @param geometryFactory
+ * @param geometryFactory the geometry factory
*/
public GeometryDataType(GeometryFactory geometryFactory) {
this.pointDataType = new PointDataType(geometryFactory);
diff --git a/baremaps-data/src/main/java/org/apache/baremaps/data/type/IntegerArrayDataType.java b/baremaps-data/src/main/java/org/apache/baremaps/data/type/IntegerArrayDataType.java
index f66bb2255..45081b4c8 100644
--- a/baremaps-data/src/main/java/org/apache/baremaps/data/type/IntegerArrayDataType.java
+++ b/baremaps-data/src/main/java/org/apache/baremaps/data/type/IntegerArrayDataType.java
@@ -17,11 +17,11 @@
package org.apache.baremaps.data.type;
-
-
import java.nio.ByteBuffer;
-/** A {@link DataType} for reading and writing lists of integers in {@link ByteBuffer}s. */
+/**
+ * A {@link DataType} for reading and writing arrays of integer values in {@link ByteBuffer}s.
+ */
public class IntegerArrayDataType implements DataType<int[]> {
/** {@inheritDoc} */
@@ -30,6 +30,7 @@ public class IntegerArrayDataType implements DataType<int[]> {
return Integer.BYTES + values.length * Integer.BYTES;
}
+ /** {@inheritDoc} */
@Override
public int size(final ByteBuffer buffer, final int position) {
return buffer.getInt(position);
diff --git a/baremaps-data/src/main/java/org/apache/baremaps/data/type/IntegerDataType.java b/baremaps-data/src/main/java/org/apache/baremaps/data/type/IntegerDataType.java
index 7fdfd23e8..7fe6bb0f6 100644
--- a/baremaps-data/src/main/java/org/apache/baremaps/data/type/IntegerDataType.java
+++ b/baremaps-data/src/main/java/org/apache/baremaps/data/type/IntegerDataType.java
@@ -22,11 +22,13 @@ package org.apache.baremaps.data.type;
import java.nio.ByteBuffer;
/**
- * A {@link DataType} for reading and writing integers in {@link ByteBuffer}s.
+ * A {@link DataType} for reading and writing integer values in {@link ByteBuffer}s.
*/
public class IntegerDataType extends MemoryAlignedDataType<Integer> {
- /** Constructs a {@link IntegerDataType}. */
+ /**
+ * Constructs an {@link IntegerDataType} with a fixed size of {@link Integer#BYTES}.
+ */
public IntegerDataType() {
super(Integer.BYTES);
}
diff --git a/baremaps-data/src/main/java/org/apache/baremaps/data/type/IntegerListDataType.java b/baremaps-data/src/main/java/org/apache/baremaps/data/type/IntegerListDataType.java
index 35b7e813e..df4525ac3 100644
--- a/baremaps-data/src/main/java/org/apache/baremaps/data/type/IntegerListDataType.java
+++ b/baremaps-data/src/main/java/org/apache/baremaps/data/type/IntegerListDataType.java
@@ -17,13 +17,13 @@
package org.apache.baremaps.data.type;
-
-
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.List;
-/** A {@link DataType} for reading and writing lists of integers in {@link ByteBuffer}s. */
+/**
+ * A {@link DataType} for reading and writing lists of integer values in {@link ByteBuffer}s.
+ */
public class IntegerListDataType implements DataType<List<Integer>> {
/** {@inheritDoc} */
@@ -32,6 +32,7 @@ public class IntegerListDataType implements DataType<List<Integer>> {
return Integer.BYTES + values.size() * Integer.BYTES;
}
+ /** {@inheritDoc} */
@Override
public int size(final ByteBuffer buffer, final int position) {
return buffer.getInt(position);
diff --git a/baremaps-data/src/main/java/org/apache/baremaps/data/type/LineStringDataType.java b/baremaps-data/src/main/java/org/apache/baremaps/data/type/LineStringDataType.java
index c6960230f..527639894 100644
--- a/baremaps-data/src/main/java/org/apache/baremaps/data/type/LineStringDataType.java
+++ b/baremaps-data/src/main/java/org/apache/baremaps/data/type/LineStringDataType.java
@@ -22,7 +22,7 @@ import org.locationtech.jts.geom.GeometryFactory;
import org.locationtech.jts.geom.LineString;
/**
- * A data type for {@link LineString} objects.
+ * A {@link DataType} for reading and writing {@link LineString} objects in {@link ByteBuffer}s.
*/
public class LineStringDataType implements DataType<LineString> {
@@ -31,14 +31,14 @@ public class LineStringDataType implements DataType<LineString> {
private final CoordinateArrayDataType coordinateArrayDataType;
/**
- * Constructs a {@code LineStringDataType} with a default {@code GeometryFactory}.
+ * Constructs a {@link LineStringDataType} with a default {@link GeometryFactory}.
*/
public LineStringDataType() {
this(new GeometryFactory());
}
/**
- * Constructs a {@code LineStringDataType} with a specified {@code GeometryFactory}.
+ * Constructs a {@link LineStringDataType} with a specified {@link GeometryFactory}.
*
* @param geometryFactory the geometry factory
*/
diff --git a/baremaps-data/src/main/java/org/apache/baremaps/data/type/ListDataType.java b/baremaps-data/src/main/java/org/apache/baremaps/data/type/ListDataType.java
index 0c0d9c819..abcda4835 100644
--- a/baremaps-data/src/main/java/org/apache/baremaps/data/type/ListDataType.java
+++ b/baremaps-data/src/main/java/org/apache/baremaps/data/type/ListDataType.java
@@ -17,23 +17,23 @@
package org.apache.baremaps.data.type;
-
-
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.List;
/**
* A {@link DataType} for reading and writing lists of objects in {@link ByteBuffer}s.
+ *
+ * @param <T> the type of elements in the list
*/
public class ListDataType<T> implements DataType<List<T>> {
public final DataType<T> dataType;
/**
- * Constructs a {@link ListDataType} with a data type.
+ * Constructs a {@link ListDataType} with a data type for its elements.
*
- * @param dataType the data type of the values
+ * @param dataType the data type of the list elements
*/
public ListDataType(final DataType<T> dataType) {
this.dataType = dataType;
@@ -49,6 +49,7 @@ public class ListDataType<T> implements DataType<List<T>> {
return size;
}
+ /** {@inheritDoc} */
@Override
public int size(final ByteBuffer buffer, final int position) {
return buffer.getInt(position);
diff --git a/baremaps-data/src/main/java/org/apache/baremaps/data/type/LonLatDataType.java b/baremaps-data/src/main/java/org/apache/baremaps/data/type/LonLatDataType.java
index 939e6e8a1..8d59c9bbc 100644
--- a/baremaps-data/src/main/java/org/apache/baremaps/data/type/LonLatDataType.java
+++ b/baremaps-data/src/main/java/org/apache/baremaps/data/type/LonLatDataType.java
@@ -32,11 +32,20 @@ public class LonLatDataType extends MemoryAlignedDataType<Coordinate> {
private static final long SHIFT = 32;
private static final long MASK = (1L << 32) - 1L;
- /** Constructs a {@link LonLatDataType}. */
+ /**
+ * Constructs a {@link LonLatDataType} with a fixed size of {@link Long#BYTES}.
+ */
public LonLatDataType() {
super(Long.BYTES);
}
+ /**
+ * Encodes longitude and latitude values into a single long value.
+ *
+ * @param lon the longitude value
+ * @param lat the latitude value
+ * @return the encoded coordinate as a long value
+ */
public static long encodeLonLat(final double lon, final double lat) {
long x = (long) (((lon + 180) / 360) * BITS);
long y = (long) (((lat + 90) / 180) * BITS);
@@ -45,11 +54,23 @@ public class LonLatDataType extends MemoryAlignedDataType<Coordinate> {
return l | r;
}
+ /**
+ * Decodes the longitude value from an encoded coordinate.
+ *
+ * @param value the encoded coordinate
+ * @return the longitude value
+ */
public static double decodeLon(final long value) {
double l = (value >>> 32);
return (l / BITS) * 360 - 180;
}
+ /**
+ * Decodes the latitude value from an encoded coordinate.
+ *
+ * @param value the encoded coordinate
+ * @return the latitude value
+ */
public static double decodeLat(final long value) {
long r = (value & MASK);
return (r / BITS) * 180 - 90;
diff --git a/baremaps-data/src/main/java/org/apache/baremaps/data/type/LongArrayDataType.java b/baremaps-data/src/main/java/org/apache/baremaps/data/type/LongArrayDataType.java
index d426b3aa6..2b03165e1 100644
--- a/baremaps-data/src/main/java/org/apache/baremaps/data/type/LongArrayDataType.java
+++ b/baremaps-data/src/main/java/org/apache/baremaps/data/type/LongArrayDataType.java
@@ -17,11 +17,11 @@
package org.apache.baremaps.data.type;
-
-
import java.nio.ByteBuffer;
-/** A {@link DataType} for reading and writing lists of longs in {@link ByteBuffer}s. */
+/**
+ * A {@link DataType} for reading and writing arrays of long values in {@link ByteBuffer}s.
+ */
public class LongArrayDataType implements DataType<long[]> {
/** {@inheritDoc} */
diff --git a/baremaps-data/src/main/java/org/apache/baremaps/data/type/LongDataType.java b/baremaps-data/src/main/java/org/apache/baremaps/data/type/LongDataType.java
index ddff6d3e7..c4d5a86b9 100644
--- a/baremaps-data/src/main/java/org/apache/baremaps/data/type/LongDataType.java
+++ b/baremaps-data/src/main/java/org/apache/baremaps/data/type/LongDataType.java
@@ -21,9 +21,14 @@ package org.apache.baremaps.data.type;
import java.nio.ByteBuffer;
-/** A {@link DataType} for reading and writing longs in {@link ByteBuffer}s. */
+/**
+ * A {@link DataType} for reading and writing long values in {@link ByteBuffer}s.
+ */
public class LongDataType extends MemoryAlignedDataType<Long> {
+ /**
+ * Constructs a {@link LongDataType} with a fixed size of {@link Long#BYTES}.
+ */
public LongDataType() {
super(Long.BYTES);
}
diff --git a/baremaps-data/src/main/java/org/apache/baremaps/data/type/LongListDataType.java b/baremaps-data/src/main/java/org/apache/baremaps/data/type/LongListDataType.java
index df8af2146..926c391e6 100644
--- a/baremaps-data/src/main/java/org/apache/baremaps/data/type/LongListDataType.java
+++ b/baremaps-data/src/main/java/org/apache/baremaps/data/type/LongListDataType.java
@@ -17,13 +17,13 @@
package org.apache.baremaps.data.type;
-
-
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.List;
-/** A {@link DataType} for reading and writing lists of longs in {@link ByteBuffer}s. */
+/**
+ * A {@link DataType} for reading and writing lists of long values in {@link ByteBuffer}s.
+ */
public class LongListDataType implements DataType<List<Long>> {
/** {@inheritDoc} */
diff --git a/baremaps-data/src/main/java/org/apache/baremaps/data/type/MapDataType.java b/baremaps-data/src/main/java/org/apache/baremaps/data/type/MapDataType.java
index 82fda0bb8..141c3894e 100644
--- a/baremaps-data/src/main/java/org/apache/baremaps/data/type/MapDataType.java
+++ b/baremaps-data/src/main/java/org/apache/baremaps/data/type/MapDataType.java
@@ -21,17 +21,30 @@ import java.nio.ByteBuffer;
import java.util.HashMap;
import java.util.Map;
+/**
+ * A {@link DataType} for reading and writing map objects in {@link ByteBuffer}s.
+ *
+ * @param <K> the type of keys in the map
+ * @param <V> the type of values in the map
+ */
public class MapDataType<K, V> implements DataType<Map<K, V>> {
private final DataType<K> keyType;
private final DataType<V> valueType;
+ /**
+ * Constructs a {@link MapDataType} with data types for keys and values.
+ *
+ * @param keyType the data type for map keys
+ * @param valueType the data type for map values
+ */
public MapDataType(final DataType<K> keyType, final DataType<V> valueType) {
this.keyType = keyType;
this.valueType = valueType;
}
+ /** {@inheritDoc} */
@Override
public int size(final Map<K, V> value) {
int size = Integer.BYTES;
@@ -42,11 +55,13 @@ public class MapDataType<K, V> implements DataType<Map<K, V>> {
return size;
}
+ /** {@inheritDoc} */
@Override
public int size(final ByteBuffer buffer, final int position) {
return buffer.getInt(position);
}
+ /** {@inheritDoc} */
@Override
public void write(final ByteBuffer buffer, final int position, final Map<K, V> value) {
buffer.putInt(position, size(value));
@@ -59,6 +74,7 @@ public class MapDataType<K, V> implements DataType<Map<K, V>> {
}
}
+ /** {@inheritDoc} */
@Override
public Map<K, V> read(final ByteBuffer buffer, final int position) {
int size = buffer.getInt(position);
diff --git a/baremaps-data/src/main/java/org/apache/baremaps/data/type/MemoryAlignedDataType.java b/baremaps-data/src/main/java/org/apache/baremaps/data/type/MemoryAlignedDataType.java
index 94c44a254..a6c6029b7 100644
--- a/baremaps-data/src/main/java/org/apache/baremaps/data/type/MemoryAlignedDataType.java
+++ b/baremaps-data/src/main/java/org/apache/baremaps/data/type/MemoryAlignedDataType.java
@@ -25,14 +25,15 @@ import java.nio.ByteBuffer;
* A {@link DataType} for reading and writing values in {@link ByteBuffer}s whose size is memory
* aligned.
*
- * @param <T>
+ * @param <T> the type of value being read or written
*/
public abstract class MemoryAlignedDataType<T> extends FixedSizeDataType<T> {
/**
- * Constructs a {@link MemoryAlignedDataType}.
+ * Constructs a {@link MemoryAlignedDataType} with a memory-aligned size.
*
- * @param size
+ * @param size the size of the value in bytes (must be a power of 2)
+ * @throws IllegalArgumentException if the size is not a power of 2
*/
protected MemoryAlignedDataType(int size) {
super(size);
diff --git a/baremaps-data/src/main/java/org/apache/baremaps/data/type/MultiLineStringDataType.java b/baremaps-data/src/main/java/org/apache/baremaps/data/type/MultiLineStringDataType.java
index fd2e773ee..373dd74b3 100644
--- a/baremaps-data/src/main/java/org/apache/baremaps/data/type/MultiLineStringDataType.java
+++ b/baremaps-data/src/main/java/org/apache/baremaps/data/type/MultiLineStringDataType.java
@@ -24,7 +24,8 @@ import org.locationtech.jts.geom.LineString;
import org.locationtech.jts.geom.MultiLineString;
/**
- * A data type for {@link MultiLineString} objects.
+ * A {@link DataType} for reading and writing {@link MultiLineString} objects in
+ * {@link ByteBuffer}s.
*/
public class MultiLineStringDataType implements DataType<MultiLineString> {
@@ -33,14 +34,14 @@ public class MultiLineStringDataType implements DataType<MultiLineString> {
private final GeometryFactory geometryFactory;
/**
- * Constructs a {@code MultiLineStringDataType} with a default {@code GeometryFactory}.
+ * Constructs a {@link MultiLineStringDataType} with a default {@link GeometryFactory}.
*/
public MultiLineStringDataType() {
this(new GeometryFactory());
}
/**
- * Constructs a {@code MultiLineStringDataType} with a specified {@code GeometryFactory}.
+ * Constructs a {@link MultiLineStringDataType} with a specified {@link GeometryFactory}.
*
* @param geometryFactory the geometry factory
*/
diff --git a/baremaps-data/src/main/java/org/apache/baremaps/data/type/MultiPointDataType.java b/baremaps-data/src/main/java/org/apache/baremaps/data/type/MultiPointDataType.java
index 8161660c6..ad63c2042 100644
--- a/baremaps-data/src/main/java/org/apache/baremaps/data/type/MultiPointDataType.java
+++ b/baremaps-data/src/main/java/org/apache/baremaps/data/type/MultiPointDataType.java
@@ -22,7 +22,7 @@ import org.locationtech.jts.geom.GeometryFactory;
import org.locationtech.jts.geom.MultiPoint;
/**
- * A data type for {@link MultiPoint} objects.
+ * A {@link DataType} for reading and writing {@link MultiPoint} objects in {@link ByteBuffer}s.
*/
public class MultiPointDataType implements DataType<MultiPoint> {
@@ -31,14 +31,14 @@ public class MultiPointDataType implements DataType<MultiPoint> {
private final GeometryFactory geometryFactory;
/**
- * Constructs a {@code MultiPointDataType} with a default {@code GeometryFactory}.
+ * Constructs a {@link MultiPointDataType} with a default {@link GeometryFactory}.
*/
public MultiPointDataType() {
this(new GeometryFactory());
}
/**
- * Constructs a {@code MultiPointDataType} with a specified {@code GeometryFactory}.
+ * Constructs a {@link MultiPointDataType} with a specified {@link GeometryFactory}.
*
* @param geometryFactory the geometry factory
*/
diff --git a/baremaps-data/src/main/java/org/apache/baremaps/data/type/MultiPolygonDataType.java b/baremaps-data/src/main/java/org/apache/baremaps/data/type/MultiPolygonDataType.java
index b7a881852..be7b68863 100644
--- a/baremaps-data/src/main/java/org/apache/baremaps/data/type/MultiPolygonDataType.java
+++ b/baremaps-data/src/main/java/org/apache/baremaps/data/type/MultiPolygonDataType.java
@@ -22,7 +22,7 @@ import java.util.ArrayList;
import org.locationtech.jts.geom.*;
/**
- * A data type for {@link GeometryCollection} objects.
+ * A {@link DataType} for reading and writing {@link MultiPolygon} objects in {@link ByteBuffer}s.
*/
public class MultiPolygonDataType implements DataType<MultiPolygon> {
@@ -31,14 +31,14 @@ public class MultiPolygonDataType implements DataType<MultiPolygon> {
private final PolygonDataType polygonDataType;
/**
- * Constructs a {@code MultiPolygonDataType} with a default {@code GeometryFactory}.
+ * Constructs a {@link MultiPolygonDataType} with a default {@link GeometryFactory}.
*/
public MultiPolygonDataType() {
this(new GeometryFactory());
}
/**
- * Constructs a {@code MultiPolygonDataType} with a specified {@code GeometryFactory}.
+ * Constructs a {@link MultiPolygonDataType} with a specified {@link GeometryFactory}.
*
* @param geometryFactory the geometry factory
*/
diff --git a/baremaps-data/src/main/java/org/apache/baremaps/data/type/NullableDataType.java b/baremaps-data/src/main/java/org/apache/baremaps/data/type/NullableDataType.java
index 1a70d6d1e..83656c6ca 100644
--- a/baremaps-data/src/main/java/org/apache/baremaps/data/type/NullableDataType.java
+++ b/baremaps-data/src/main/java/org/apache/baremaps/data/type/NullableDataType.java
@@ -21,15 +21,19 @@ package org.apache.baremaps.data.type;
import java.nio.ByteBuffer;
-/** A {@link DataType} for reading and writing nullable values in {@link ByteBuffer}s. */
+/**
+ * A {@link DataType} for reading and writing nullable values in {@link ByteBuffer}s.
+ *
+ * @param <T> the type of value being read or written
+ */
public class NullableDataType<T> implements DataType<T> {
private final DataType<T> dataType;
/**
- * Constructs a {@link NullableDataType} with a data type.
+ * Constructs a {@link NullableDataType} with a data type for the wrapped value.
*
- * @param dataType the data type of the values
+ * @param dataType the data type for the non-null values
*/
public NullableDataType(final DataType<T> dataType) {
this.dataType = dataType;
diff --git a/baremaps-data/src/main/java/org/apache/baremaps/data/type/PairDataType.java b/baremaps-data/src/main/java/org/apache/baremaps/data/type/PairDataType.java
index 4f6bc37c5..37d52c963 100644
--- a/baremaps-data/src/main/java/org/apache/baremaps/data/type/PairDataType.java
+++ b/baremaps-data/src/main/java/org/apache/baremaps/data/type/PairDataType.java
@@ -23,12 +23,23 @@ import java.nio.ByteBuffer;
import java.util.Objects;
import org.apache.baremaps.data.type.PairDataType.Pair;
-/** A {@link DataType} for reading and writing pairs of values in {@link ByteBuffer}s. */
+/**
+ * A {@link DataType} for reading and writing pairs of values in {@link ByteBuffer}s.
+ *
+ * @param <L> the type of the left value in the pair
+ * @param <R> the type of the right value in the pair
+ */
public class PairDataType<L, R> extends FixedSizeDataType<Pair<L, R>> {
private final FixedSizeDataType<L> left;
private final FixedSizeDataType<R> right;
+ /**
+ * Constructs a {@link PairDataType} with data types for left and right values.
+ *
+ * @param left the data type for the left value
+ * @param right the data type for the right value
+ */
public PairDataType(final FixedSizeDataType<L> left, final FixedSizeDataType<R> right) {
super(left.size() + right.size());
this.left = left;
@@ -50,21 +61,43 @@ public class PairDataType<L, R> extends FixedSizeDataType<Pair<L, R>> {
right.read(buffer, position + left.size()));
}
+ /**
+ * A class representing a pair of values.
+ *
+ * @param <L> the type of the left value
+ * @param <R> the type of the right value
+ */
public static class Pair<L, R> {
private final L left;
private final R right;
+ /**
+ * Constructs a pair with left and right values.
+ *
+ * @param left the left value
+ * @param right the right value
+ */
public Pair(L left, R right) {
this.left = left;
this.right = right;
}
+ /**
+ * Returns the left value of the pair.
+ *
+ * @return the left value
+ */
public L left() {
return left;
}
+ /**
+ * Returns the right value of the pair.
+ *
+ * @return the right value
+ */
public R right() {
return right;
}
diff --git a/baremaps-data/src/main/java/org/apache/baremaps/data/type/PointDataType.java b/baremaps-data/src/main/java/org/apache/baremaps/data/type/PointDataType.java
index e48156acb..ed3e2a33a 100644
--- a/baremaps-data/src/main/java/org/apache/baremaps/data/type/PointDataType.java
+++ b/baremaps-data/src/main/java/org/apache/baremaps/data/type/PointDataType.java
@@ -23,21 +23,21 @@ import org.locationtech.jts.geom.GeometryFactory;
import org.locationtech.jts.geom.Point;
/**
- * A data type for {@link Point} objects.
+ * A {@link DataType} for reading and writing {@link Point} objects in {@link ByteBuffer}s.
*/
public class PointDataType implements DataType<Point> {
private final GeometryFactory geometryFactory;
/**
- * Constructs a {@code PointDataType} with a default {@code GeometryFactory}.
+ * Constructs a {@link PointDataType} with a default {@link GeometryFactory}.
*/
public PointDataType() {
this(new GeometryFactory());
}
/**
- * Constructs a {@code PointDataType} with a specified {@code GeometryFactory}.
+ * Constructs a {@link PointDataType} with a specified {@link GeometryFactory}.
*
* @param geometryFactory the geometry factory
*/
diff --git a/baremaps-data/src/main/java/org/apache/baremaps/data/type/PolygonDataType.java b/baremaps-data/src/main/java/org/apache/baremaps/data/type/PolygonDataType.java
index 86822094d..6bfb32146 100644
--- a/baremaps-data/src/main/java/org/apache/baremaps/data/type/PolygonDataType.java
+++ b/baremaps-data/src/main/java/org/apache/baremaps/data/type/PolygonDataType.java
@@ -25,7 +25,7 @@ import org.locationtech.jts.geom.LinearRing;
import org.locationtech.jts.geom.Polygon;
/**
- * A data type for {@link Polygon} objects.
+ * A {@link DataType} for reading and writing {@link Polygon} objects in {@link ByteBuffer}s.
*/
public class PolygonDataType implements DataType<Polygon> {
@@ -34,14 +34,14 @@ public class PolygonDataType implements DataType<Polygon> {
private final GeometryFactory geometryFactory;
/**
- * Constructs a {@code PolygonDataType} with a default {@code GeometryFactory}.
+ * Constructs a {@link PolygonDataType} with a default {@link GeometryFactory}.
*/
public PolygonDataType() {
this(new GeometryFactory());
}
/**
- * Constructs a {@code PolygonDataType} with a specified {@code GeometryFactory}.
+ * Constructs a {@link PolygonDataType} with a specified {@link GeometryFactory}.
*
* @param geometryFactory the geometry factory
*/
diff --git a/baremaps-data/src/main/java/org/apache/baremaps/data/type/RowDataType.java b/baremaps-data/src/main/java/org/apache/baremaps/data/type/RowDataType.java
index ba8bede60..a4ba70582 100644
--- a/baremaps-data/src/main/java/org/apache/baremaps/data/type/RowDataType.java
+++ b/baremaps-data/src/main/java/org/apache/baremaps/data/type/RowDataType.java
@@ -27,10 +27,13 @@ import org.apache.baremaps.store.DataRowImpl;
import org.apache.baremaps.store.DataSchema;
/**
- * A data type for rows.
+ * A {@link DataType} for reading and writing {@link DataRow} objects in {@link ByteBuffer}s.
*/
public class RowDataType implements DataType<DataRow> {
+ /**
+ * Map of data types for each of the supported column types.
+ */
private static final EnumMap<Type, DataType> types = new EnumMap<>(Type.class);
static {
@@ -55,10 +58,16 @@ public class RowDataType implements DataType<DataRow> {
private final DataSchema rowType;
+ /**
+ * Constructs a {@link RowDataType} with a specified schema.
+ *
+ * @param rowType the data schema defining the row's structure
+ */
public RowDataType(DataSchema rowType) {
this.rowType = rowType;
}
+ /** {@inheritDoc} */
@Override
public int size(final DataRow row) {
int size = Integer.BYTES;
@@ -72,11 +81,13 @@ public class RowDataType implements DataType<DataRow> {
return size;
}
+ /** {@inheritDoc} */
@Override
public int size(final ByteBuffer buffer, final int position) {
return buffer.getInt(position);
}
+ /** {@inheritDoc} */
@Override
public void write(final ByteBuffer buffer, final int position, final DataRow row) {
int p = position + Integer.BYTES;
@@ -92,6 +103,7 @@ public class RowDataType implements DataType<DataRow> {
buffer.putInt(position, p - position);
}
+ /** {@inheritDoc} */
@Override
public DataRow read(final ByteBuffer buffer, final int position) {
int p = position + Integer.BYTES;
diff --git a/baremaps-data/src/main/java/org/apache/baremaps/data/type/ShortArrayDataType.java b/baremaps-data/src/main/java/org/apache/baremaps/data/type/ShortArrayDataType.java
index a45bb37bd..c242a25eb 100644
--- a/baremaps-data/src/main/java/org/apache/baremaps/data/type/ShortArrayDataType.java
+++ b/baremaps-data/src/main/java/org/apache/baremaps/data/type/ShortArrayDataType.java
@@ -21,7 +21,9 @@ package org.apache.baremaps.data.type;
import java.nio.ByteBuffer;
-/** A {@link DataType} for reading and writing lists of shorts in {@link ByteBuffer}s. */
+/**
+ * A {@link DataType} for reading and writing arrays of short values in {@link ByteBuffer}s.
+ */
public class ShortArrayDataType implements DataType<short[]> {
/** {@inheritDoc} */
diff --git a/baremaps-data/src/main/java/org/apache/baremaps/data/type/ShortDataType.java b/baremaps-data/src/main/java/org/apache/baremaps/data/type/ShortDataType.java
index 02ca4d1d3..5605d4711 100644
--- a/baremaps-data/src/main/java/org/apache/baremaps/data/type/ShortDataType.java
+++ b/baremaps-data/src/main/java/org/apache/baremaps/data/type/ShortDataType.java
@@ -21,10 +21,14 @@ package org.apache.baremaps.data.type;
import java.nio.ByteBuffer;
-/** A {@link DataType} for reading and writing shorts in {@link ByteBuffer}s. */
+/**
+ * A {@link DataType} for reading and writing short values in {@link ByteBuffer}s.
+ */
public class ShortDataType extends FixedSizeDataType<Short> {
- /** Constructs a {@link ShortDataType}. */
+ /**
+ * Constructs a {@link ShortDataType} with a fixed size of {@link Short#BYTES}.
+ */
public ShortDataType() {
super(Short.BYTES);
}
diff --git a/baremaps-data/src/main/java/org/apache/baremaps/data/type/ShortListDataType.java b/baremaps-data/src/main/java/org/apache/baremaps/data/type/ShortListDataType.java
index 1f99d24a7..8888cddd0 100644
--- a/baremaps-data/src/main/java/org/apache/baremaps/data/type/ShortListDataType.java
+++ b/baremaps-data/src/main/java/org/apache/baremaps/data/type/ShortListDataType.java
@@ -17,13 +17,13 @@
package org.apache.baremaps.data.type;
-
-
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.List;
-/** A {@link DataType} for reading and writing lists of shorts in {@link ByteBuffer}s. */
+/**
+ * A {@link DataType} for reading and writing lists of short values in {@link ByteBuffer}s.
+ */
public class ShortListDataType implements DataType<List<Short>> {
/** {@inheritDoc} */
diff --git a/baremaps-data/src/main/java/org/apache/baremaps/data/type/SmallIntegerDataType.java b/baremaps-data/src/main/java/org/apache/baremaps/data/type/SmallIntegerDataType.java
index b8ccd7e5f..b3cfd3277 100644
--- a/baremaps-data/src/main/java/org/apache/baremaps/data/type/SmallIntegerDataType.java
+++ b/baremaps-data/src/main/java/org/apache/baremaps/data/type/SmallIntegerDataType.java
@@ -17,19 +17,21 @@
package org.apache.baremaps.data.type;
-
-
import java.nio.ByteBuffer;
-/** A {@link DataType} for reading and writing small integers in {@link ByteBuffer}s. */
+/**
+ * A {@link DataType} for reading and writing small integer values in {@link ByteBuffer}s with a
+ * customizable storage size.
+ */
public class SmallIntegerDataType extends FixedSizeDataType<Integer> {
private final int n;
/**
- * Constructs a {@link SmallIntegerDataType}.
+ * Constructs a {@link SmallIntegerDataType} with a specified number of bytes.
*
- * @param n the number of bytes used to store the integer
+ * @param n the number of bytes used to store the integer (must be between 1 and 4)
+ * @throws IllegalArgumentException if n is less than 1 or greater than 4
*/
public SmallIntegerDataType(int n) {
super(n);
diff --git a/baremaps-data/src/main/java/org/apache/baremaps/data/type/SmallLongDataType.java b/baremaps-data/src/main/java/org/apache/baremaps/data/type/SmallLongDataType.java
index 2e7812f04..cb0a4f70b 100644
--- a/baremaps-data/src/main/java/org/apache/baremaps/data/type/SmallLongDataType.java
+++ b/baremaps-data/src/main/java/org/apache/baremaps/data/type/SmallLongDataType.java
@@ -17,19 +17,21 @@
package org.apache.baremaps.data.type;
-
-
import java.nio.ByteBuffer;
-/** A {@link DataType} for reading and writing small longs in {@link ByteBuffer}s. */
+/**
+ * A {@link DataType} for reading and writing small long values in {@link ByteBuffer}s with a
+ * customizable storage size.
+ */
public class SmallLongDataType extends FixedSizeDataType<Long> {
private final int n;
/**
- * Constructs a {@link SmallIntegerDataType}.
+ * Constructs a {@link SmallLongDataType} with a specified number of bytes.
*
- * @param n the number of bytes used to store the integer
+ * @param n the number of bytes used to store the long value (must be between 1 and 8)
+ * @throws IllegalArgumentException if n is less than 1 or greater than 8
*/
public SmallLongDataType(int n) {
super(n);
diff --git a/baremaps-data/src/main/java/org/apache/baremaps/data/type/StringDataType.java b/baremaps-data/src/main/java/org/apache/baremaps/data/type/StringDataType.java
index a3eb253ad..7050140f8 100644
--- a/baremaps-data/src/main/java/org/apache/baremaps/data/type/StringDataType.java
+++ b/baremaps-data/src/main/java/org/apache/baremaps/data/type/StringDataType.java
@@ -23,7 +23,7 @@ import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
/**
- * A {@link DataType} for reading and writing strings in {@link ByteBuffer}s.
+ * A {@link DataType} for reading and writing string values in {@link ByteBuffer}s.
*/
public class StringDataType implements DataType<String> {
diff --git a/baremaps-data/src/main/java/org/apache/baremaps/data/type/WKBDataType.java b/baremaps-data/src/main/java/org/apache/baremaps/data/type/WKBDataType.java
index 1c3b3bfed..abd6c2ae1 100644
--- a/baremaps-data/src/main/java/org/apache/baremaps/data/type/WKBDataType.java
+++ b/baremaps-data/src/main/java/org/apache/baremaps/data/type/WKBDataType.java
@@ -17,19 +17,19 @@
package org.apache.baremaps.data.type;
-
-
import static org.locationtech.jts.io.WKBConstants.wkbNDR;
import java.nio.ByteBuffer;
import org.locationtech.jts.geom.Geometry;
import org.locationtech.jts.geom.GeometryFactory;
-import org.locationtech.jts.geom.PrecisionModel;
import org.locationtech.jts.io.ParseException;
import org.locationtech.jts.io.WKBReader;
import org.locationtech.jts.io.WKBWriter;
-/** A {@link DataType} for reading and writing {@link Geometry} in {@link ByteBuffer}s. */
+/**
+ * A {@link DataType} for reading and writing {@link Geometry} objects in Well-Known Binary (WKB)
+ * format in {@link ByteBuffer}s.
+ */
public class WKBDataType implements DataType<Geometry> {
/** {@inheritDoc} */
@@ -70,14 +70,11 @@ public class WKBDataType implements DataType<Geometry> {
return deserialize(bytes);
}
- public static final GeometryFactory GEOMETRY_FACTORY_WGS84 =
- new GeometryFactory(new PrecisionModel(), 4326);
-
/**
- * Serializes a geometry in the WKB format.
+ * Serializes a geometry into the WKB format.
*
- * @param geometry
- * @return
+ * @param geometry the geometry to serialize
+ * @return the serialized geometry as a byte array, or null if the input is null
*/
private static byte[] serialize(Geometry geometry) {
if (geometry == null) {
@@ -88,10 +85,11 @@ public class WKBDataType implements DataType<Geometry> {
}
/**
- * Deserializes a geometry in the WKB format.
+ * Deserializes a geometry from the WKB format.
*
- * @param wkb
- * @return
+ * @param wkb the WKB byte array to deserialize
+ * @return the deserialized geometry, or null if the input is null
+ * @throws IllegalArgumentException if the WKB cannot be parsed
*/
private static Geometry deserialize(byte[] wkb) {
if (wkb == null) {
diff --git a/baremaps-data/src/test/java/org/apache/baremaps/data/AppendOnlyLogTest.java b/baremaps-data/src/test/java/org/apache/baremaps/data/AppendOnlyLogTest.java
index 96de22641..d9b354550 100644
--- a/baremaps-data/src/test/java/org/apache/baremaps/data/AppendOnlyLogTest.java
+++ b/baremaps-data/src/test/java/org/apache/baremaps/data/AppendOnlyLogTest.java
@@ -35,7 +35,10 @@ class AppendOnlyLogTest {
@Test
void addFixedSizeData() {
- var collection = new AppendOnlyLog<>(new IntegerDataType(), new OffHeapMemory(1 << 10));
+ var collection = AppendOnlyLog.<Integer>builder()
+ .dataType(new IntegerDataType())
+ .memory(new OffHeapMemory(1 << 10))
+ .build();
for (int i = 0; i < 1 << 20; i++) {
assertEquals(Long.BYTES + (i << 2), collection.addPositioned(i));
}
@@ -46,7 +49,10 @@ class AppendOnlyLogTest {
@Test
void addVariableSizeValues() {
- var collection = new AppendOnlyLog<>(new IntegerListDataType(), new OffHeapMemory(1 << 10));
+ var collection = AppendOnlyLog.<ArrayList<Integer>>builder()
+ .dataType(new IntegerListDataType())
+ .memory(new OffHeapMemory(1 << 10))
+ .build();
var random = new Random(0);
var positions = new ArrayList<Long>();
var values = new ArrayList<ArrayList<Integer>>();
@@ -69,7 +75,10 @@ class AppendOnlyLogTest {
@MethodSource("org.apache.baremaps.data.type.DataTypeProvider#dataTypes")
void testAllDataTypes(DataType dataType, Object value) {
var num = 1000;
- var collection = new AppendOnlyLog<>(dataType, new OffHeapMemory(1 << 22));
+ var collection = AppendOnlyLog.builder()
+ .dataType(dataType)
+ .memory(new OffHeapMemory(1 << 22))
+ .build();
// write values
for (int i = 0; i < num; i++) {
diff --git a/baremaps-data/src/test/java/org/apache/baremaps/data/DataListTest.java b/baremaps-data/src/test/java/org/apache/baremaps/data/DataListTest.java
index 63c1c21a2..6f697fba8 100644
--- a/baremaps-data/src/test/java/org/apache/baremaps/data/DataListTest.java
+++ b/baremaps-data/src/test/java/org/apache/baremaps/data/DataListTest.java
@@ -75,9 +75,19 @@ class DataListTest {
static Stream<Arguments> listProvider() {
return Stream.of(
- Arguments.of(new FixedSizeDataList<>(new LongDataType())),
- Arguments.of(new IndexedDataList<>(new MemoryAlignedDataList<>(new LongDataType()),
- new AppendOnlyLog<>(new LongDataType()))),
- Arguments.of(new MemoryAlignedDataList<>(new LongDataType())));
+ Arguments.of(FixedSizeDataList.<Long>builder()
+ .dataType(new LongDataType())
+ .build()),
+ Arguments.of(IndexedDataList.<Long>builder()
+ .index(MemoryAlignedDataList.<Long>builder()
+ .dataType(new LongDataType())
+ .build())
+ .values(AppendOnlyLog.<Long>builder()
+ .dataType(new LongDataType())
+ .build())
+ .build()),
+ Arguments.of(MemoryAlignedDataList.<Long>builder()
+ .dataType(new LongDataType())
+ .build()));
}
}
diff --git a/baremaps-data/src/test/java/org/apache/baremaps/data/DataMapTest.java b/baremaps-data/src/test/java/org/apache/baremaps/data/DataMapTest.java
index f62c79520..a66a16a67 100644
--- a/baremaps-data/src/test/java/org/apache/baremaps/data/DataMapTest.java
+++ b/baremaps-data/src/test/java/org/apache/baremaps/data/DataMapTest.java
@@ -165,16 +165,39 @@ class DataMapTest {
return Stream
.of(
Arguments.of(
- new IndexedDataMap<>(
- new AppendOnlyLog<>(new LongDataType(), new OffHeapMemory()))),
- Arguments.of(new MonotonicFixedSizeDataMap<>(
- new MemoryAlignedDataList<>(new LongDataType(), new OffHeapMemory()))),
- Arguments.of(new MonotonicDataMap<>(
- new MemoryAlignedDataList<>(
- new PairDataType<>(new LongDataType(), new LongDataType()),
- new OffHeapMemory()),
- new AppendOnlyLog<>(new LongDataType(), new OffHeapMemory()))),
- Arguments.of(new MonotonicPairedDataMap<>(new MemoryAlignedDataList<>(
- new PairDataType<>(new LongDataType(), new LongDataType())))));
+ IndexedDataMap.<Long>builder()
+ .values(AppendOnlyLog.<Long>builder()
+ .dataType(new LongDataType())
+ .memory(new OffHeapMemory())
+ .build())
+ .build()),
+ Arguments.of(MonotonicFixedSizeDataMap.<Long>builder()
+ .values(MemoryAlignedDataList.<Long>builder()
+ .dataType(new LongDataType())
+ .memory(new OffHeapMemory())
+ .build())
+ .build()),
+ Arguments.of(MonotonicDataMap.<Long>builder()
+ .keys(MemoryAlignedDataList.<PairDataType.Pair<Long, Long>>builder()
+ .dataType(new PairDataType<>(new LongDataType(), new LongDataType()))
+ .memory(new OffHeapMemory())
+ .build())
+ .values(AppendOnlyLog.<Long>builder()
+ .dataType(new LongDataType())
+ .memory(new OffHeapMemory())
+ .build())
+ .build()),
+ Arguments.of(MonotonicPairedDataMap.<Long>builder()
+ .values(MemoryAlignedDataList.<PairDataType.Pair<Long, Long>>builder()
+ .dataType(new PairDataType<>(new LongDataType(), new LongDataType()))
+ .build())
+ .build()),
+ Arguments.of(DirectHashDataMap.<Long>builder()
+ .keyType(new LongDataType())
+ .dataType(new LongDataType())
+ .keyMemory(new OffHeapMemory())
+ .valueMemory(new OffHeapMemory())
+ .capacity(1000)
+ .build()));
}
}
diff --git a/baremaps-data/src/test/java/org/apache/baremaps/data/SizedDataListTest.java b/baremaps-data/src/test/java/org/apache/baremaps/data/SizedDataListTest.java
index f7ec72652..cb96ea10d 100644
--- a/baremaps-data/src/test/java/org/apache/baremaps/data/SizedDataListTest.java
+++ b/baremaps-data/src/test/java/org/apache/baremaps/data/SizedDataListTest.java
@@ -36,13 +36,19 @@ class SizedDataListTest {
void segmentsTooSmall() {
var dataType = new LongDataType();
var memory = new OffHeapMemory(4);
- assertThrows(DataCollectionException.class, () -> new FixedSizeDataList<>(dataType, memory));
+ assertThrows(DataCollectionException.class, () -> FixedSizeDataList.<Long>builder()
+ .dataType(dataType)
+ .memory(memory)
+ .build());
}
@ParameterizedTest
@MethodSource("org.apache.baremaps.data.memory.MemoryProvider#memories")
void appendFixedSizeValues(Memory memory) throws IOException {
- var list = new FixedSizeDataList<>(new LongDataType(), memory);
+ var list = FixedSizeDataList.<Long>builder()
+ .dataType(new LongDataType())
+ .memory(memory)
+ .build();
for (int i = 0; i < 1 << 10; i++) {
assertEquals(i, list.addIndexed((long) i));
}
diff --git a/baremaps-data/src/test/java/org/apache/baremaps/data/collection/IndexedDataMapTest.java b/baremaps-data/src/test/java/org/apache/baremaps/data/collection/IndexedDataMapTest.java
index 5eaa87fa8..666172923 100644
--- a/baremaps-data/src/test/java/org/apache/baremaps/data/collection/IndexedDataMapTest.java
+++ b/baremaps-data/src/test/java/org/apache/baremaps/data/collection/IndexedDataMapTest.java
@@ -37,7 +37,11 @@ class IndexedDataMapTest {
@BeforeEach
void setUp() {
- map = new IndexedDataMap<>(new AppendOnlyLog<>(new IntegerDataType()));
+ map = IndexedDataMap.<Integer>builder()
+ .values(AppendOnlyLog.<Integer>builder()
+ .dataType(new IntegerDataType())
+ .build())
+ .build();
}
@AfterEach
diff --git a/baremaps-data/src/test/java/org/apache/baremaps/data/collection/MemoryAlignedDataMapTest.java b/baremaps-data/src/test/java/org/apache/baremaps/data/collection/MemoryAlignedDataMapTest.java
index 241cc4c26..912b2b26c 100644
--- a/baremaps-data/src/test/java/org/apache/baremaps/data/collection/MemoryAlignedDataMapTest.java
+++ b/baremaps-data/src/test/java/org/apache/baremaps/data/collection/MemoryAlignedDataMapTest.java
@@ -37,7 +37,10 @@ class MemoryAlignedDataMapTest {
@BeforeEach
void setUp() {
- map = new MemoryAlignedDataMap<>(new IntegerDataType(), new OnHeapMemory(1024));
+ map = MemoryAlignedDataMap.<Integer>builder()
+ .dataType(new IntegerDataType())
+ .memory(new OnHeapMemory(1024))
+ .build();
}
@AfterEach
diff --git a/baremaps-data/src/test/java/org/apache/baremaps/data/sort/BinarySearchTest.java b/baremaps-data/src/test/java/org/apache/baremaps/data/sort/BinarySearchTest.java
index 3182d5b36..4d0f0af54 100644
--- a/baremaps-data/src/test/java/org/apache/baremaps/data/sort/BinarySearchTest.java
+++ b/baremaps-data/src/test/java/org/apache/baremaps/data/sort/BinarySearchTest.java
@@ -28,7 +28,9 @@ class BinarySearchTest {
@Test
void binarySearch() {
- var list = new MemoryAlignedDataList<>(new LongDataType());
+ var list = MemoryAlignedDataList.<Long>builder()
+ .dataType(new LongDataType())
+ .build();
for (long i = 0; i < 1000; i++) {
list.add(i);
}
diff --git a/baremaps-data/src/test/java/org/apache/baremaps/data/sort/ExternalMergeSortTest.java b/baremaps-data/src/test/java/org/apache/baremaps/data/sort/ExternalMergeSortTest.java
index 87b8ff345..0bb72050b 100644
--- a/baremaps-data/src/test/java/org/apache/baremaps/data/sort/ExternalMergeSortTest.java
+++ b/baremaps-data/src/test/java/org/apache/baremaps/data/sort/ExternalMergeSortTest.java
@@ -53,9 +53,16 @@ class ExternalMergeSortTest {
stringsAsc = strings.stream().sorted(Comparator.naturalOrder()).toList();
stringsDsc = strings.stream().sorted(Comparator.reverseOrder()).toList();
stringsDistinct = stringsAsc.stream().distinct().toList();
- supplier = () -> new IndexedDataList<>(
- new MemoryAlignedDataList<>(new LongDataType(), new OnHeapMemory()),
- new AppendOnlyLog<>(new StringDataType(), new OnHeapMemory()));
+ supplier = () -> IndexedDataList.<String>builder()
+ .index(MemoryAlignedDataList.<Long>builder()
+ .dataType(new LongDataType())
+ .memory(new OnHeapMemory())
+ .build())
+ .values(AppendOnlyLog.<String>builder()
+ .dataType(new StringDataType())
+ .memory(new OnHeapMemory())
+ .build())
+ .build();
input = supplier.get();
output = supplier.get();
for (var string : strings) {