Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ repositories {
}

ext {
rlibVersion = "10.0.alpha8"
rlibVersion = "10.0.alpha9"
}

dependencies {
Expand Down
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
rootProject.version = "10.0.alpha8"
rootProject.version = "10.0.alpha9"
group = 'javasabr.rlib'

allprojects {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@ static <E> Array<E> empty(Class<? super E> type) {
return new ImmutableArray<>(ClassUtils.unsafeCast(type));
}

static <E> ArrayBuilder<E> builder(Class<? super E> type) {
return new ArrayBuilder<>(type);
}

static <E> Array<E> of(E single) {
@SuppressWarnings("unchecked")
Class<E> type = (Class<E>) single.getClass();
Expand Down Expand Up @@ -95,6 +99,14 @@ static <E> Array<E> copyOf(Array<E> array) {
return new ImmutableArray<>(array.type(), array.toArray());
}

static <E> Array<E> copyOf(Class<? super E> type, Collection<E> collection) {
if (collection instanceof MutableArray<E> mutableArray) {
return copyOf(mutableArray);
}
E[] array = collection.toArray(ArrayUtils.create(type, collection.size()));
return ImmutableArray.trustWrap(array);
}

Class<E> type();

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package javasabr.rlib.collections.array;

import java.util.Collection;
import lombok.AccessLevel;
import lombok.experimental.FieldDefaults;

@FieldDefaults(level = AccessLevel.PRIVATE, makeFinal = true)
public final class ArrayBuilder<E> {

MutableArray<E> elements;

public ArrayBuilder(Class<? super E> type) {
this.elements = ArrayFactory.mutableArray(type);
}

public ArrayBuilder<E> add(E element) {
elements.add(element);
return this;
}

@SafeVarargs
public final ArrayBuilder<E> add(E... other) {
elements.addAll(other);
return this;
}

public ArrayBuilder<E> add(Collection<E> other) {
elements.addAll(other);
return this;
}

public ArrayBuilder<E> add(Array<E> other) {
elements.addAll(other);
return this;
}

public Array<E> build() {
return Array.copyOf(elements);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import javasabr.rlib.collections.dictionary.impl.DefaultMutableHashBasedLongToRefDictionary;
import javasabr.rlib.collections.dictionary.impl.DefaultMutableHashBasedRefToRefDictionary;
import javasabr.rlib.collections.dictionary.impl.StampedLockBasedHashBasedRefToRefDictionary;
import javasabr.rlib.collections.dictionary.impl.gc.optimized.GcOptimizedMutableHashBasedIntToRefDictionary;
import lombok.experimental.UtilityClass;

@UtilityClass
Expand All @@ -16,6 +17,10 @@ public static <V> MutableIntToRefDictionary<V> mutableIntToRefDictionary() {
return new DefaultMutableHashBasedIntToRefDictionary<>();
}

public static <V> MutableIntToRefDictionary<V> gcOptimizedIntToRefDictionary() {
return new GcOptimizedMutableHashBasedIntToRefDictionary<>();
}

public static <V> MutableLongToRefDictionary<V> mutableLongToRefDictionary() {
return new DefaultMutableHashBasedLongToRefDictionary<>();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,21 @@

public interface RefToRefDictionary<K, V> extends Dictionary<K, V> {

static <K, V> RefToRefDictionaryBuilder<K, V> builder() {
return new RefToRefDictionaryBuilder<>();
}

static <K, V> RefToRefDictionaryBuilder<K, V> builder(
Class<? super K> keyType,
Class<? super V> valueType) {
return new RefToRefDictionaryBuilder<>();
}

static <K, V> RefToRefDictionaryBuilder<K, V> startWith(K key, V value) {
return new RefToRefDictionaryBuilder<K, V>()
.put(key, value);
}

static <K, V> RefToRefEntry<K, V> entry(K key, V value) {
return new SimpleRefToRefEntry<>(key, value);
}
Expand All @@ -22,6 +37,14 @@ static <K, V> RefToRefDictionary<K, V> of(K k1, V v1, K k2, V v2) {
return ofEntries(entry(k1, v1), entry(k2, v2));
}

static <K, V> RefToRefDictionary<K, V> of(K k1, V v1, K k2, V v2, K k3, V v3) {
return ofEntries(entry(k1, v1), entry(k2, v2), entry(k3, v3));
}

static <K, V> RefToRefDictionary<K, V> of(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4) {
return ofEntries(entry(k1, v1), entry(k2, v2), entry(k3, v3), entry(k4, v4));
}

@SafeVarargs
static <K, V> RefToRefDictionary<K, V> ofEntries(RefToRefEntry<K, V>... entries) {
MutableRefToRefDictionary<K, V> mutable = DictionaryFactory.mutableRefToRefDictionary();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package javasabr.rlib.collections.dictionary;

import java.util.Map;
import lombok.AccessLevel;
import lombok.experimental.FieldDefaults;

@FieldDefaults(level = AccessLevel.PRIVATE, makeFinal = true)
public class RefToRefDictionaryBuilder<K, V> {

MutableRefToRefDictionary<K, V> elements;

public RefToRefDictionaryBuilder() {
this.elements = DictionaryFactory.mutableRefToRefDictionary();
}

public RefToRefDictionaryBuilder<K, V> put(K key, V value) {
this.elements.put(key, value);
return this;
}

public RefToRefDictionaryBuilder<K, V> put(RefToRefDictionary<K, V> other) {
this.elements.putAll(other);
return this;
}

public RefToRefDictionaryBuilder<K, V> put(Map<K, V> other) {
for (Map.Entry<K, V> entry : other.entrySet()) {
elements.put(entry.getKey(), entry.getValue());
}
return this;
}

public RefToRefDictionary<K, V> build() {
return elements.toReadOnly();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@
import javasabr.rlib.collections.dictionary.Dictionary;

public abstract class AbstractDictionary<K, V> implements Dictionary<K, V> {

}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package javasabr.rlib.collections.dictionary.impl;

import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
Expand All @@ -11,6 +12,7 @@
import javasabr.rlib.collections.array.MutableArray;
import javasabr.rlib.collections.array.UnsafeMutableArray;
import javasabr.rlib.collections.dictionary.LinkedHashEntry;
import javasabr.rlib.collections.dictionary.RefToRefDictionary;
import javasabr.rlib.collections.dictionary.UnsafeRefToRefDictionary;
import org.jspecify.annotations.Nullable;

Expand Down Expand Up @@ -161,6 +163,37 @@ public MutableArray<V> values(MutableArray<V> container) {
return container;
}

@Override
public int hashCode() {
return Arrays.hashCode(entries());
}

@Override
public boolean equals(Object obj) {
if (!(obj instanceof RefToRefDictionary<?, ?> another)) {
return false;
} else if (size() != another.size()) {
return false;
}

RefToRefDictionary<Object, Object> toCompare = (RefToRefDictionary<Object, Object>) obj;

for (E entry : entries()) {
while (entry != null) {
if (!toCompare.containsKey(entry.key())) {
return false;
}
V value = entry.value();
Object anotherValue = toCompare.get(entry.key());
if (!Objects.equals(value, anotherValue)) {
return false;
}
entry = entry.next();
}
}
return true;
}

@Override
public String toString() {

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
package javasabr.rlib.collections.dictionary.impl.gc.optimized;

import java.util.Arrays;
import java.util.Deque;
import javasabr.rlib.collections.deque.DequeFactory;
import javasabr.rlib.collections.dictionary.IntToRefDictionary;
import javasabr.rlib.collections.dictionary.impl.AbstractMutableHashBasedIntToRefDictionary;
import javasabr.rlib.collections.dictionary.impl.ImmutableHashBasedIntToRefDictionary;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.experimental.Accessors;
import lombok.experimental.FieldDefaults;
import org.jspecify.annotations.Nullable;

@Getter
@Accessors(fluent = true)
@FieldDefaults(level = AccessLevel.PROTECTED)
public class GcOptimizedMutableHashBasedIntToRefDictionary<V> extends
AbstractMutableHashBasedIntToRefDictionary<V, ReusableLinkedHashIntToRefEntry<V>> {

private static final int MAX_POOL_SIZE = 40;

final Deque<ReusableLinkedHashIntToRefEntry<V>> entryPool;
@Nullable ReusableLinkedHashIntToRefEntry<V>[] entries;
int size;
int threshold;

public GcOptimizedMutableHashBasedIntToRefDictionary() {
this(DEFAULT_INITIAL_CAPACITY, DEFAULT_LOAD_FACTOR);
}

public GcOptimizedMutableHashBasedIntToRefDictionary(int initCapacity, float loadFactor) {
super(loadFactor);
//noinspection unchecked
this.entries = new ReusableLinkedHashIntToRefEntry[initCapacity];
this.threshold = (int) (initCapacity * loadFactor);
this.entryPool = DequeFactory.arrayBasedBased(ReusableLinkedHashIntToRefEntry.class);
}

@Override
public boolean isEmpty() {
return size < 1;
}

@Override
protected int incrementSize() {
return size++;
}

@Override
protected int decrementSize() {
return size--;
}

@Override
public void clear() {
for (ReusableLinkedHashIntToRefEntry<V> entry : entries()) {
while (entry != null) {
ReusableLinkedHashIntToRefEntry<V> next = entry.next();
deallocate(entry);
entry = next;
}
}
Arrays.fill(entries, null);
size = 0;
}

@Override
protected void threshold(int threshold) {
this.threshold = threshold;
}

@Override
protected void entries(@Nullable ReusableLinkedHashIntToRefEntry<V>[] entries) {
this.entries = entries;
}

@Nullable
@Override
public V remove(int key) {
ReusableLinkedHashIntToRefEntry<V> entry = removeEntryForKey(key);
if (entry == null) {
return null;
}
V value = entry.value();
deallocate(entry);
return value;
}

@Override
protected ReusableLinkedHashIntToRefEntry<V> allocate(
int hash,
int key,
@Nullable V value,
@Nullable ReusableLinkedHashIntToRefEntry<V> next) {
ReusableLinkedHashIntToRefEntry<V> reused = entryPool.pollLast();
if (reused != null) {
return reused.reinit(next, key, value, hash);
}
return new ReusableLinkedHashIntToRefEntry<>(next, key, value, hash);
}

private void deallocate(ReusableLinkedHashIntToRefEntry<V> entry) {
if (entryPool.size() < MAX_POOL_SIZE) {
entryPool.addLast(entry.clear());
}
}

@Nullable
@Override
protected ReusableLinkedHashIntToRefEntry<V>[] allocate(int length) {
//noinspection unchecked
return new ReusableLinkedHashIntToRefEntry[length];
}

@Override
public IntToRefDictionary<V> toReadOnly() {
@Nullable ReusableLinkedHashIntToRefEntry<V>[] copied = Arrays.copyOf(entries, entries.length);
return new ImmutableHashBasedIntToRefDictionary<>(copied, size);
}
}
Loading
Loading