Utils: javadocs

This commit is contained in:
2025-05-13 22:55:25 +02:00
parent d0b45177dd
commit 7784d975d7
8 changed files with 177 additions and 28 deletions

View File

@@ -1,18 +0,0 @@
package com.usatiuk.utils;
import java.nio.ByteBuffer;
public class ByteUtils {
public static byte[] longToBytes(long val) {
return ByteBuffer.wrap(new byte[8]).putLong(val).array();
}
public static long bytesToLong(byte[] bytes) {
return ByteBuffer.wrap(bytes).getLong();
}
// Returns a ByteBuffer of size 8 with position reset
public static ByteBuffer longToBb(long val) {
return ByteBuffer.allocate(8).putLong(val).flip();
}
}

View File

@@ -9,6 +9,9 @@ import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
/**
* Allows to lock arbitrary keys.
*/
public class DataLocker {
private final ConcurrentHashMap<Object, WeakReference<ReentrantLock>> _locks = new ConcurrentHashMap<>();
private static final Cleaner CLEANER = Cleaner.create();
@@ -36,6 +39,12 @@ public class DataLocker {
}
}
/**
* Locks the data and returns an AutoCloseable that unlocks it when closed.
*
* @param data the data to lock
* @return an AutoCloseable that unlocks the data when closed
*/
@Nonnull
public AutoCloseableNoThrow lock(Object data) {
var lock = getTag(data);
@@ -43,6 +52,13 @@ public class DataLocker {
return lock::unlock;
}
/**
* Tries to lock the data and returns an AutoCloseable that unlocks it when closed.
* If the lock is not acquired, returns null.
*
* @param data the data to lock
* @return an AutoCloseable that unlocks the data when closed, or null if the lock was not acquired
*/
@Nullable
public AutoCloseableNoThrow tryLock(Object data) {
var lock = getTag(data);

View File

@@ -7,20 +7,38 @@ import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.function.Function;
/**
* Blocking queue that delays the objects for a given time, and deduplicates them.
*
* @param <T> the type of the objects in the queue
*/
public class HashSetDelayedBlockingQueue<T> {
private final LinkedHashMap<T, SetElement<T>> _set = new LinkedHashMap<>();
private final Object _sleepSynchronizer = new Object();
private long _delay;
private boolean _closed = false;
/**
* Creates a new HashSetDelayedBlockingQueue with the specified delay.
*
* @param delay the delay in milliseconds
*/
public HashSetDelayedBlockingQueue(long delay) {
_delay = delay;
}
/**
* @return the delay in milliseconds
*/
public long getDelay() {
return _delay;
}
/**
* Sets the delay for the queue.
*
* @param delay the delay in milliseconds
*/
public void setDelay(long delay) {
synchronized (_sleepSynchronizer) {
_delay = delay;
@@ -28,8 +46,12 @@ public class HashSetDelayedBlockingQueue<T> {
}
}
// If there's object with key in the queue, don't do anything
// Returns whether it was added or not
/**
* Adds the object to the queue if it doesn't exist.
*
* @param el the object to add
* @return true if the object was added, false if it already exists
*/
public boolean add(T el) {
synchronized (this) {
if (_closed) throw new IllegalStateException("Adding to a queue that is closed!");
@@ -43,9 +65,12 @@ public class HashSetDelayedBlockingQueue<T> {
}
// Adds the object to the queue, if it exists re-adds it
// With no delay
// Returns the old object, or null
/**
* Adds the object to the queue with no delay.
*
* @param el the object to add
* @return the old object if it existed, null otherwise
*/
public T addNoDelay(T el) {
synchronized (this) {
if (_closed) throw new IllegalStateException("Adding to a queue that is closed!");
@@ -60,8 +85,12 @@ public class HashSetDelayedBlockingQueue<T> {
}
}
// Adds the object to the queue, if it exists re-adds it with a new delay
// Returns the old object, or null
/**
* Adds the object to the queue, if it exists re-adds it with a new delay
*
* @param el the object to add
* @return the old object if it existed, null otherwise
*/
public T readd(T el) {
synchronized (this) {
if (_closed) throw new IllegalStateException("Adding to a queue that is closed!");
@@ -76,8 +105,13 @@ public class HashSetDelayedBlockingQueue<T> {
}
}
// Merges the object with the old one
// Returns the old object, or null
/**
* Merges the object with the old one.
*
* @param el the object to merge
* @param transformer the function to transform the old object
* @return the old object if it existed, null otherwise
*/
public T merge(T el, Function<T, T> transformer) {
synchronized (this) {
if (_closed) throw new IllegalStateException("Adding to a queue that is closed!");
@@ -97,7 +131,12 @@ public class HashSetDelayedBlockingQueue<T> {
}
}
// Removes the object
/**
* Removes the object from the queue.
*
* @param el the object to remove
* @return the removed object, or null if it didn't exist
*/
public T remove(T el) {
synchronized (this) {
var rem = _set.remove(el);
@@ -106,6 +145,13 @@ public class HashSetDelayedBlockingQueue<T> {
}
}
/**
* Gets the object from the queue, waiting for it if necessary.
*
* @param timeout the timeout in milliseconds, or -1 for no timeout
* @return the object, or null if it timed out
* @throws InterruptedException if the thread is interrupted
*/
public T get(long timeout) throws InterruptedException {
long startedWaiting = timeout > 0 ? System.currentTimeMillis() : -1;
@@ -148,6 +194,12 @@ public class HashSetDelayedBlockingQueue<T> {
throw new InterruptedException();
}
/**
* Gets the object from the queue, waiting for it if necessary.
*
* @return the object
* @throws InterruptedException if the thread is interrupted
*/
public T get() throws InterruptedException {
T ret;
do {
@@ -155,6 +207,11 @@ public class HashSetDelayedBlockingQueue<T> {
return ret;
}
/**
* Checks if the queue has an object that is ready to be processed.
*
* @return true if there is an object ready, false otherwise
*/
public boolean hasImmediate() {
synchronized (this) {
if (_set.isEmpty()) return false;
@@ -166,6 +223,11 @@ public class HashSetDelayedBlockingQueue<T> {
}
}
/**
* Tries to get the object from the queue without waiting.
*
* @return the object, or null if it doesn't exist
*/
@Nullable
public T tryGet() {
synchronized (this) {
@@ -182,6 +244,11 @@ public class HashSetDelayedBlockingQueue<T> {
}
}
/**
* Gets all objects from the queue that are ready to be processed.
*
* @return a collection of objects
*/
public Collection<T> getAll() {
ArrayList<T> out = new ArrayList<>();
@@ -198,6 +265,11 @@ public class HashSetDelayedBlockingQueue<T> {
return out;
}
/**
* Closes the queue and returns all objects in it.
*
* @return a collection of objects
*/
public Collection<T> close() {
synchronized (this) {
_closed = true;
@@ -207,6 +279,12 @@ public class HashSetDelayedBlockingQueue<T> {
}
}
/**
* Gets all objects from the queue, waiting for them if necessary.
*
* @return a collection of objects
* @throws InterruptedException if the thread is interrupted
*/
public Collection<T> getAllWait() throws InterruptedException {
Collection<T> out;
do {
@@ -214,6 +292,13 @@ public class HashSetDelayedBlockingQueue<T> {
return out;
}
/**
* Gets all objects from the queue, waiting for them if necessary.
*
* @param max the maximum number of objects to get
* @return a collection of objects
* @throws InterruptedException if the thread is interrupted
*/
public Collection<T> getAllWait(int max) throws InterruptedException {
Collection<T> out;
do {
@@ -221,6 +306,14 @@ public class HashSetDelayedBlockingQueue<T> {
return out;
}
/**
* Gets all objects from the queue, waiting for them if necessary.
*
* @param max the maximum number of objects to get
* @param timeout the timeout in milliseconds, or -1 for no timeout
* @return a collection of objects
* @throws InterruptedException if the thread is interrupted
*/
public Collection<T> getAllWait(int max, long timeout) throws InterruptedException {
ArrayList<T> out = new ArrayList<>();

View File

@@ -3,8 +3,21 @@ package com.usatiuk.utils;
import java.util.List;
import java.util.function.Function;
/**
* Utility class for list operations.
*/
public class ListUtils {
/**
* Prepends an item to a list and maps the rest of the list using a provided function.
*
* @param item The item to prepend.
* @param suffix The list to append to.
* @param suffixFn The function to map the suffix items.
* @param <T> The type of the items in the list.
* @param <T_V> The type of the mapped items.
* @return A new list with the prepended item and mapped suffix items.
*/
public static <T, T_V> List<T_V> prependAndMap(T_V item, List<T> suffix, Function<T, T_V> suffixFn) {
T_V[] arr = (T_V[]) new Object[suffix.size() + 1];
arr[0] = item;
@@ -14,6 +27,14 @@ public class ListUtils {
return List.of(arr);
}
/**
* Prepends an item to a list.
*
* @param item The item to prepend.
* @param suffix The list to append to.
* @param <T> The type of the items in the list.
* @return A new list with the prepended item and the original suffix items.
*/
public static <T> List<T> prepend(T item, List<T> suffix) {
T[] arr = (T[]) new Object[suffix.size() + 1];
arr[0] = item;
@@ -23,6 +44,15 @@ public class ListUtils {
return List.of(arr);
}
/**
* Maps a list using a provided function.
*
* @param suffix The list to map.
* @param suffixFn The function to map the items.
* @param <T> The type of the items in the list.
* @param <T_V> The type of the mapped items.
* @return A new list with the mapped items.
*/
public static <T, T_V> List<T_V> map(List<T> suffix, Function<T, T_V> suffixFn) {
T_V[] arr = (T_V[]) new Object[suffix.size()];
for (int i = 0; i < suffix.size(); i++) {

View File

@@ -10,6 +10,13 @@ import java.io.IOException;
import java.io.InputStream;
import java.io.Serializable;
/**
* Utility class for serialization and deserialization of objects.
* <p>
* This class provides methods to serialize and deserialize objects using Java's built-in serialization mechanism.
* It also includes methods to handle byte arrays and input streams for serialization and deserialization.
* </p>
*/
public abstract class SerializationHelper {
// Taken from SerializationUtils
public static <T> T deserialize(final InputStream inputStream) {

View File

@@ -6,6 +6,9 @@ import io.grpc.StatusRuntimeException;
import javax.annotation.Nullable;
/**
* A {@link StatusRuntimeException} that does not fill in the stack trace.
*/
public class StatusRuntimeExceptionNoStacktrace extends StatusRuntimeException {
public StatusRuntimeExceptionNoStacktrace(Status status) {
super(status);

View File

@@ -5,6 +5,9 @@ import java.lang.invoke.MethodHandle;
import java.nio.ByteBuffer;
import java.util.function.Consumer;
/**
* Utility class for creating uninitialized ByteBuffers, to avoid zeroing memory unnecessarily.
*/
public class UninitializedByteBuffer {
private static final Linker LINKER = Linker.nativeLinker();
private static final MethodHandle malloc = LINKER.downcallHandle(
@@ -16,6 +19,12 @@ public class UninitializedByteBuffer {
FunctionDescriptor.ofVoid(ValueLayout.ADDRESS)
);
/**
* Allocates a new uninitialized ByteBuffer of the specified capacity.
*
* @param capacity the capacity of the ByteBuffer
* @return a new uninitialized ByteBuffer
*/
public static ByteBuffer allocate(int capacity) {
UnsafeAccessor.NIO.reserveMemory(capacity, capacity);
@@ -38,6 +47,12 @@ public class UninitializedByteBuffer {
return reint.asByteBuffer();
}
/**
* Gets the address of the given ByteBuffer.
*
* @param buffer the ByteBuffer to get the address of
* @return the address of the ByteBuffer
*/
public static long getAddress(ByteBuffer buffer) {
return UnsafeAccessor.NIO.getBufferAddress(buffer);
}

View File

@@ -6,6 +6,9 @@ import sun.misc.Unsafe;
import java.lang.reflect.Field;
/**
* Provides access to the {@link Unsafe} class and {@link JavaNioAccess} class.
*/
public abstract class UnsafeAccessor {
public static final JavaNioAccess NIO;
public static final Unsafe UNSAFE;