Skip to content

Commit 7294584

Browse files
authored
fix: Fix the edge case in collection values from Dictionary (#69)
1 parent c067bec commit 7294584

7 files changed

Lines changed: 72 additions & 46 deletions

File tree

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ repositories {
4545
}
4646
4747
ext {
48-
rlibVersion = "10.0.alpha15"
48+
rlibVersion = "10.0.alpha16"
4949
}
5050
5151
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.alpha15"
1+
rootProject.version = "10.0.alpha16"
22
group = 'javasabr.rlib'
33

44
allprojects {

rlib-collections/src/main/java/javasabr/rlib/collections/array/impl/AbstractMutableArray.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -208,8 +208,7 @@ public UnsafeMutableArray<E> prepareForSize(int expectedSize) {
208208
}
209209
return this;
210210
}
211-
212-
211+
213212
@Override
214213
public UnsafeMutableArray<E> trimToSize() {
215214
@Nullable E[] wrapped = wrapped();

rlib-collections/src/main/java/javasabr/rlib/collections/dictionary/impl/util/LinkedEntryUtils.java

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,8 +59,10 @@ public static <V, E extends LinkedEntry<E> & RefEntry<V>> int values(
5959
if (size < 1) {
6060
return -1;
6161
}
62+
int extra = 10; // if we have several values per one dictionary cell
63+
int reserved = Math.min(limit, size) + extra;
6264
UnsafeMutableArray<V> unsafe = container.asUnsafe();
63-
unsafe.prepareForSize(container.size() + Math.min(limit, size));
65+
unsafe.prepareForSize(container.size() + reserved);
6466
for (int i = startIndex, length = entries.length; i < length; i++) {
6567
if (unsafe.size() >= limit) {
6668
return i;
@@ -69,7 +71,12 @@ public static <V, E extends LinkedEntry<E> & RefEntry<V>> int values(
6971
while (entry != null) {
7072
V value = entry.value();
7173
if (value != null) {
74+
if (reserved < 1) {
75+
unsafe.prepareForSize(container.size() + extra);
76+
reserved = extra;
77+
}
7278
unsafe.unsafeAdd(value);
79+
reserved--;
7380
}
7481
entry = entry.next();
7582
}

rlib-collections/src/test/java/javasabr/rlib/collections/dictionary/MutableRefToRefDictionaryTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -213,7 +213,7 @@ void shouldAppendDictionary(MutableRefToRefDictionary<String, String> dictionary
213213
void shouldIterateAllValuesUsingPartIndex(MutableRefToRefDictionary<String, String> dictionary) {
214214
// given:
215215
var expectedValues = ArrayFactory.mutableArray(String.class);
216-
for (int i = 10; i < 1000; i += 8) {
216+
for (int i = 10; i < 1000; i++) {
217217
var value = "value_" + i;
218218
var key = "key_" + i;
219219
expectedValues.add(value);

rlib-logger-api/src/main/java/javasabr/rlib/logger/api/LoggerLevel.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,10 @@
1616
@Accessors(fluent = true)
1717
@FieldDefaults(level = AccessLevel.PRIVATE, makeFinal = true)
1818
public enum LoggerLevel {
19-
INFO("INFO", " ", true, true),
20-
DEBUG("DEBUG", " ", false, false),
21-
WARNING("WARN", "", true, true),
22-
ERROR("ERROR", " ", true, true);
19+
INFO("INFO", " ", true, true),
20+
DEBUG("DEBUG", " ", false, false),
21+
WARNING("WARN", " ", true, true),
22+
ERROR("ERROR", " ", true, true);
2323

2424
/**
2525
* The number of log levels.

rlib-logger-impl/src/test/java/javasabr/rlib/logger/impl/DefaultLoggerTest.java

Lines changed: 56 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -2,67 +2,87 @@
22

33
import static org.assertj.core.api.Assertions.assertThat;
44

5+
import java.util.Collection;
56
import javasabr.rlib.collections.array.ArrayFactory;
67
import javasabr.rlib.collections.array.LockableArray;
8+
import javasabr.rlib.collections.operation.LockableOperations;
79
import javasabr.rlib.logger.api.LoggerLevel;
810
import javasabr.rlib.logger.api.LoggerListener;
911
import javasabr.rlib.logger.api.LoggerManager;
10-
import org.junit.jupiter.api.AfterAll;
11-
import org.junit.jupiter.api.BeforeAll;
12+
import org.junit.jupiter.api.AfterEach;
1213
import org.junit.jupiter.api.BeforeEach;
1314
import org.junit.jupiter.api.Test;
15+
import org.junit.jupiter.api.parallel.ResourceLock;
1416

15-
public class DefaultLoggerTest {
17+
@ResourceLock("LoggerListeners")
18+
class DefaultLoggerTest {
1619

17-
private static final LockableArray<String> WROTE_DATA = ArrayFactory
20+
private static final LockableArray<String> LOGS_DATA = ArrayFactory
1821
.stampedLockBasedArray(String.class);
22+
private static final LockableOperations<LockableArray<String>> LOGS_DATA_OPERATIONS =
23+
LOGS_DATA.operations();
24+
25+
private static final LoggerListener LOGGER_LISTENER = text -> LOGS_DATA_OPERATIONS
26+
.inWriteLock(text, Collection::add);
1927

20-
private static final LoggerListener LOGGER_LISTENER = text -> {
21-
long stamp = WROTE_DATA.writeLock();
22-
try {
23-
WROTE_DATA.add(text);
24-
} finally {
25-
WROTE_DATA.writeUnlock(stamp);
26-
}
27-
};
28-
29-
@BeforeAll
30-
static void registerListener() {
31-
LoggerManager.addListener(LOGGER_LISTENER);
32-
}
33-
34-
@AfterAll
35-
static void unregisterListener() {
28+
@BeforeEach
29+
void prepare() {
3630
LoggerManager.addListener(LOGGER_LISTENER);
31+
LOGS_DATA_OPERATIONS
32+
.inWriteLock(Collection::clear);
3733
}
38-
39-
@BeforeEach
40-
void clearWroteData() {
41-
long stamp = WROTE_DATA.writeLock();
42-
try {
43-
WROTE_DATA.clear();
44-
} finally {
45-
WROTE_DATA.writeUnlock(stamp);
46-
}
34+
35+
@AfterEach
36+
void cleanup() {
37+
LOGS_DATA_OPERATIONS.inWriteLock(Collection::clear);
38+
LoggerManager.removeListener(LOGGER_LISTENER);
4739
}
4840

4941
@Test
5042
void shouldCreateDefaultLoggerImplementation() {
51-
var logger = LoggerManager.getLogger(DefaultLoggerTest.class);
52-
assertThat(logger)
43+
assertThat(LoggerManager.getLogger(DefaultLoggerTest.class))
5344
.isInstanceOf(DefaultLogger.class);
5445
}
5546

5647
@Test
5748
void shouldWriteDataToDefaultLoggerImplementation() {
58-
49+
// given:
5950
var logger = LoggerManager.getLogger(DefaultLoggerTest.class);
60-
logger.print(LoggerLevel.ERROR, "test data");
51+
logger.overrideEnabled(LoggerLevel.DEBUG, true);
52+
logger.overrideEnabled(LoggerLevel.WARNING, true);
53+
logger.overrideEnabled(LoggerLevel.ERROR, true);
54+
logger.overrideEnabled(LoggerLevel.INFO, true);
55+
56+
// when:
57+
logger.print(LoggerLevel.ERROR, "test error data");
58+
59+
// then:
60+
assertThat(LOGS_DATA.size()).isEqualTo(1);
61+
assertThat(LOGS_DATA.get(0)).startsWith("ERROR ");
62+
assertThat(LOGS_DATA.get(0)).endsWith("DefaultLoggerTest: test error data");
63+
64+
// when:
65+
logger.print(LoggerLevel.WARNING, "test warn data 2");
66+
67+
// then:
68+
assertThat(LOGS_DATA.size()).isEqualTo(2);
69+
assertThat(LOGS_DATA.get(1)).startsWith("WARN ");
70+
assertThat(LOGS_DATA.get(1)).endsWith("DefaultLoggerTest: test warn data 2");
71+
72+
// when:
73+
logger.print(LoggerLevel.DEBUG, "test debug data 3");
6174

62-
assertThat(WROTE_DATA.size()).isEqualTo(1);
75+
// then:
76+
assertThat(LOGS_DATA.size()).isEqualTo(3);
77+
assertThat(LOGS_DATA.get(2)).startsWith("DEBUG ");
78+
assertThat(LOGS_DATA.get(2)).endsWith("DefaultLoggerTest: test debug data 3");
6379

64-
logger.print(LoggerLevel.ERROR, "test data 2");
80+
// when:
81+
logger.print(LoggerLevel.INFO, "test info data 4");
6582

66-
assertThat(WROTE_DATA.size()).isEqualTo(2);
83+
// then:
84+
assertThat(LOGS_DATA.size()).isEqualTo(4);
85+
assertThat(LOGS_DATA.get(3)).startsWith("INFO ");
86+
assertThat(LOGS_DATA.get(3)).endsWith("DefaultLoggerTest: test info data 4");
6787
}
6888
}

0 commit comments

Comments
 (0)