Skip to content

Commit 1d111e6

Browse files
authored
Extend API v8 (#53)
1 parent b7448ec commit 1d111e6

26 files changed

+471
-39
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ repositories {
1414
}
1515
1616
ext {
17-
rlibVersion = "10.0.alpha8"
17+
rlibVersion = "10.0.alpha9"
1818
}
1919
2020
dependencies {

build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
rootProject.version = "10.0.alpha8"
1+
rootProject.version = "10.0.alpha9"
22
group = 'javasabr.rlib'
33

44
allprojects {

rlib-collections/src/main/java/javasabr/rlib/collections/array/Array.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,10 @@ static <E> Array<E> empty(Class<? super E> type) {
2323
return new ImmutableArray<>(ClassUtils.unsafeCast(type));
2424
}
2525

26+
static <E> ArrayBuilder<E> builder(Class<? super E> type) {
27+
return new ArrayBuilder<>(type);
28+
}
29+
2630
static <E> Array<E> of(E single) {
2731
@SuppressWarnings("unchecked")
2832
Class<E> type = (Class<E>) single.getClass();
@@ -95,6 +99,14 @@ static <E> Array<E> copyOf(Array<E> array) {
9599
return new ImmutableArray<>(array.type(), array.toArray());
96100
}
97101

102+
static <E> Array<E> copyOf(Class<? super E> type, Collection<E> collection) {
103+
if (collection instanceof MutableArray<E> mutableArray) {
104+
return copyOf(mutableArray);
105+
}
106+
E[] array = collection.toArray(ArrayUtils.create(type, collection.size()));
107+
return ImmutableArray.trustWrap(array);
108+
}
109+
98110
Class<E> type();
99111

100112
/**
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
package javasabr.rlib.collections.array;
2+
3+
import java.util.Collection;
4+
import lombok.AccessLevel;
5+
import lombok.experimental.FieldDefaults;
6+
7+
@FieldDefaults(level = AccessLevel.PRIVATE, makeFinal = true)
8+
public final class ArrayBuilder<E> {
9+
10+
MutableArray<E> elements;
11+
12+
public ArrayBuilder(Class<? super E> type) {
13+
this.elements = ArrayFactory.mutableArray(type);
14+
}
15+
16+
public ArrayBuilder<E> add(E element) {
17+
elements.add(element);
18+
return this;
19+
}
20+
21+
@SafeVarargs
22+
public final ArrayBuilder<E> add(E... other) {
23+
elements.addAll(other);
24+
return this;
25+
}
26+
27+
public ArrayBuilder<E> add(Collection<E> other) {
28+
elements.addAll(other);
29+
return this;
30+
}
31+
32+
public ArrayBuilder<E> add(Array<E> other) {
33+
elements.addAll(other);
34+
return this;
35+
}
36+
37+
public Array<E> build() {
38+
return Array.copyOf(elements);
39+
}
40+
}

rlib-collections/src/main/java/javasabr/rlib/collections/dictionary/DictionaryFactory.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import javasabr.rlib.collections.dictionary.impl.DefaultMutableHashBasedLongToRefDictionary;
55
import javasabr.rlib.collections.dictionary.impl.DefaultMutableHashBasedRefToRefDictionary;
66
import javasabr.rlib.collections.dictionary.impl.StampedLockBasedHashBasedRefToRefDictionary;
7+
import javasabr.rlib.collections.dictionary.impl.gc.optimized.GcOptimizedMutableHashBasedIntToRefDictionary;
78
import lombok.experimental.UtilityClass;
89

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

20+
public static <V> MutableIntToRefDictionary<V> gcOptimizedIntToRefDictionary() {
21+
return new GcOptimizedMutableHashBasedIntToRefDictionary<>();
22+
}
23+
1924
public static <V> MutableLongToRefDictionary<V> mutableLongToRefDictionary() {
2025
return new DefaultMutableHashBasedLongToRefDictionary<>();
2126
}

rlib-collections/src/main/java/javasabr/rlib/collections/dictionary/RefToRefDictionary.java

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,21 @@
66

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

9+
static <K, V> RefToRefDictionaryBuilder<K, V> builder() {
10+
return new RefToRefDictionaryBuilder<>();
11+
}
12+
13+
static <K, V> RefToRefDictionaryBuilder<K, V> builder(
14+
Class<? super K> keyType,
15+
Class<? super V> valueType) {
16+
return new RefToRefDictionaryBuilder<>();
17+
}
18+
19+
static <K, V> RefToRefDictionaryBuilder<K, V> startWith(K key, V value) {
20+
return new RefToRefDictionaryBuilder<K, V>()
21+
.put(key, value);
22+
}
23+
924
static <K, V> RefToRefEntry<K, V> entry(K key, V value) {
1025
return new SimpleRefToRefEntry<>(key, value);
1126
}
@@ -22,6 +37,14 @@ static <K, V> RefToRefDictionary<K, V> of(K k1, V v1, K k2, V v2) {
2237
return ofEntries(entry(k1, v1), entry(k2, v2));
2338
}
2439

40+
static <K, V> RefToRefDictionary<K, V> of(K k1, V v1, K k2, V v2, K k3, V v3) {
41+
return ofEntries(entry(k1, v1), entry(k2, v2), entry(k3, v3));
42+
}
43+
44+
static <K, V> RefToRefDictionary<K, V> of(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4) {
45+
return ofEntries(entry(k1, v1), entry(k2, v2), entry(k3, v3), entry(k4, v4));
46+
}
47+
2548
@SafeVarargs
2649
static <K, V> RefToRefDictionary<K, V> ofEntries(RefToRefEntry<K, V>... entries) {
2750
MutableRefToRefDictionary<K, V> mutable = DictionaryFactory.mutableRefToRefDictionary();
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
package javasabr.rlib.collections.dictionary;
2+
3+
import java.util.Map;
4+
import lombok.AccessLevel;
5+
import lombok.experimental.FieldDefaults;
6+
7+
@FieldDefaults(level = AccessLevel.PRIVATE, makeFinal = true)
8+
public class RefToRefDictionaryBuilder<K, V> {
9+
10+
MutableRefToRefDictionary<K, V> elements;
11+
12+
public RefToRefDictionaryBuilder() {
13+
this.elements = DictionaryFactory.mutableRefToRefDictionary();
14+
}
15+
16+
public RefToRefDictionaryBuilder<K, V> put(K key, V value) {
17+
this.elements.put(key, value);
18+
return this;
19+
}
20+
21+
public RefToRefDictionaryBuilder<K, V> put(RefToRefDictionary<K, V> other) {
22+
this.elements.putAll(other);
23+
return this;
24+
}
25+
26+
public RefToRefDictionaryBuilder<K, V> put(Map<K, V> other) {
27+
for (Map.Entry<K, V> entry : other.entrySet()) {
28+
elements.put(entry.getKey(), entry.getValue());
29+
}
30+
return this;
31+
}
32+
33+
public RefToRefDictionary<K, V> build() {
34+
return elements.toReadOnly();
35+
}
36+
}

rlib-collections/src/main/java/javasabr/rlib/collections/dictionary/impl/AbstractDictionary.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,5 @@
33
import javasabr.rlib.collections.dictionary.Dictionary;
44

55
public abstract class AbstractDictionary<K, V> implements Dictionary<K, V> {
6+
67
}

rlib-collections/src/main/java/javasabr/rlib/collections/dictionary/impl/AbstractHashBasedRefToRefDictionary.java

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package javasabr.rlib.collections.dictionary.impl;
22

3+
import java.util.Arrays;
34
import java.util.Collection;
45
import java.util.Collections;
56
import java.util.Iterator;
@@ -11,6 +12,7 @@
1112
import javasabr.rlib.collections.array.MutableArray;
1213
import javasabr.rlib.collections.array.UnsafeMutableArray;
1314
import javasabr.rlib.collections.dictionary.LinkedHashEntry;
15+
import javasabr.rlib.collections.dictionary.RefToRefDictionary;
1416
import javasabr.rlib.collections.dictionary.UnsafeRefToRefDictionary;
1517
import org.jspecify.annotations.Nullable;
1618

@@ -161,6 +163,37 @@ public MutableArray<V> values(MutableArray<V> container) {
161163
return container;
162164
}
163165

166+
@Override
167+
public int hashCode() {
168+
return Arrays.hashCode(entries());
169+
}
170+
171+
@Override
172+
public boolean equals(Object obj) {
173+
if (!(obj instanceof RefToRefDictionary<?, ?> another)) {
174+
return false;
175+
} else if (size() != another.size()) {
176+
return false;
177+
}
178+
179+
RefToRefDictionary<Object, Object> toCompare = (RefToRefDictionary<Object, Object>) obj;
180+
181+
for (E entry : entries()) {
182+
while (entry != null) {
183+
if (!toCompare.containsKey(entry.key())) {
184+
return false;
185+
}
186+
V value = entry.value();
187+
Object anotherValue = toCompare.get(entry.key());
188+
if (!Objects.equals(value, anotherValue)) {
189+
return false;
190+
}
191+
entry = entry.next();
192+
}
193+
}
194+
return true;
195+
}
196+
164197
@Override
165198
public String toString() {
166199

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
package javasabr.rlib.collections.dictionary.impl.gc.optimized;
2+
3+
import java.util.Arrays;
4+
import java.util.Deque;
5+
import javasabr.rlib.collections.deque.DequeFactory;
6+
import javasabr.rlib.collections.dictionary.IntToRefDictionary;
7+
import javasabr.rlib.collections.dictionary.impl.AbstractMutableHashBasedIntToRefDictionary;
8+
import javasabr.rlib.collections.dictionary.impl.ImmutableHashBasedIntToRefDictionary;
9+
import lombok.AccessLevel;
10+
import lombok.Getter;
11+
import lombok.experimental.Accessors;
12+
import lombok.experimental.FieldDefaults;
13+
import org.jspecify.annotations.Nullable;
14+
15+
@Getter
16+
@Accessors(fluent = true)
17+
@FieldDefaults(level = AccessLevel.PROTECTED)
18+
public class GcOptimizedMutableHashBasedIntToRefDictionary<V> extends
19+
AbstractMutableHashBasedIntToRefDictionary<V, ReusableLinkedHashIntToRefEntry<V>> {
20+
21+
private static final int MAX_POOL_SIZE = 40;
22+
23+
final Deque<ReusableLinkedHashIntToRefEntry<V>> entryPool;
24+
@Nullable ReusableLinkedHashIntToRefEntry<V>[] entries;
25+
int size;
26+
int threshold;
27+
28+
public GcOptimizedMutableHashBasedIntToRefDictionary() {
29+
this(DEFAULT_INITIAL_CAPACITY, DEFAULT_LOAD_FACTOR);
30+
}
31+
32+
public GcOptimizedMutableHashBasedIntToRefDictionary(int initCapacity, float loadFactor) {
33+
super(loadFactor);
34+
//noinspection unchecked
35+
this.entries = new ReusableLinkedHashIntToRefEntry[initCapacity];
36+
this.threshold = (int) (initCapacity * loadFactor);
37+
this.entryPool = DequeFactory.arrayBasedBased(ReusableLinkedHashIntToRefEntry.class);
38+
}
39+
40+
@Override
41+
public boolean isEmpty() {
42+
return size < 1;
43+
}
44+
45+
@Override
46+
protected int incrementSize() {
47+
return size++;
48+
}
49+
50+
@Override
51+
protected int decrementSize() {
52+
return size--;
53+
}
54+
55+
@Override
56+
public void clear() {
57+
for (ReusableLinkedHashIntToRefEntry<V> entry : entries()) {
58+
while (entry != null) {
59+
ReusableLinkedHashIntToRefEntry<V> next = entry.next();
60+
deallocate(entry);
61+
entry = next;
62+
}
63+
}
64+
Arrays.fill(entries, null);
65+
size = 0;
66+
}
67+
68+
@Override
69+
protected void threshold(int threshold) {
70+
this.threshold = threshold;
71+
}
72+
73+
@Override
74+
protected void entries(@Nullable ReusableLinkedHashIntToRefEntry<V>[] entries) {
75+
this.entries = entries;
76+
}
77+
78+
@Nullable
79+
@Override
80+
public V remove(int key) {
81+
ReusableLinkedHashIntToRefEntry<V> entry = removeEntryForKey(key);
82+
if (entry == null) {
83+
return null;
84+
}
85+
V value = entry.value();
86+
deallocate(entry);
87+
return value;
88+
}
89+
90+
@Override
91+
protected ReusableLinkedHashIntToRefEntry<V> allocate(
92+
int hash,
93+
int key,
94+
@Nullable V value,
95+
@Nullable ReusableLinkedHashIntToRefEntry<V> next) {
96+
ReusableLinkedHashIntToRefEntry<V> reused = entryPool.pollLast();
97+
if (reused != null) {
98+
return reused.reinit(next, key, value, hash);
99+
}
100+
return new ReusableLinkedHashIntToRefEntry<>(next, key, value, hash);
101+
}
102+
103+
private void deallocate(ReusableLinkedHashIntToRefEntry<V> entry) {
104+
if (entryPool.size() < MAX_POOL_SIZE) {
105+
entryPool.addLast(entry.clear());
106+
}
107+
}
108+
109+
@Nullable
110+
@Override
111+
protected ReusableLinkedHashIntToRefEntry<V>[] allocate(int length) {
112+
//noinspection unchecked
113+
return new ReusableLinkedHashIntToRefEntry[length];
114+
}
115+
116+
@Override
117+
public IntToRefDictionary<V> toReadOnly() {
118+
@Nullable ReusableLinkedHashIntToRefEntry<V>[] copied = Arrays.copyOf(entries, entries.length);
119+
return new ImmutableHashBasedIntToRefDictionary<>(copied, size);
120+
}
121+
}

0 commit comments

Comments
 (0)