Improve ArrayCharBag

This commit is contained in:
MrLetsplay 2024-06-18 19:24:27 +02:00
parent f918093097
commit 941a0973e7
Signed by: mr
SSH Key Fingerprint: SHA256:92jBH80vpXyaZHjaIl47pjRq+Yt7XGTArqQg1V7hSqg
3 changed files with 131 additions and 6 deletions

View File

@ -61,6 +61,12 @@
<version>5.10.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-params</artifactId>
<version>5.10.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.java-websocket</groupId>
<artifactId>Java-WebSocket</artifactId>

View File

@ -27,15 +27,40 @@ public class ArrayCharBag implements CharBag {
this(Collections.emptyList());
}
/**
* Finds the index of a character if it is contained within the bag, or the index it would be inserted at if it is not contained in the bag.
* @param character The character to find
* @return The index the character was found or would be inserted at
*/
private int indexOf(Char character) {
int lo = 0, hi = chars.size() - 1;
while(hi >= lo) {
int mid = (lo + hi) / 2;
Char c = get(mid);
int comp = Util.compareChars(c, character);
if(comp == 0) return mid;
if(comp < 0) {
lo = mid + 1;
}else {
hi = mid - 1;
}
}
return lo;
}
@Override
public int add(Char character) {
int i = 0;
// TODO: use binary search
while(i < chars.size() && Util.compareChars(chars.get(i), character) < 0) i++;
int i = indexOf(character);
if(i < chars.size() && Util.compareChars(chars.get(i), character) == 0) {
debugValues.increment(DEBUG_INSERTIONS_DROPPED);
return -1;
}
chars.add(i, character);
debugValues.increment(DEBUG_INSERTIONS);
return i;
@ -43,13 +68,12 @@ public class ArrayCharBag implements CharBag {
@Override
public int remove(Char character) {
int i = 0;
// TODO: use binary search
while(i < chars.size() && Util.compareChars(chars.get(i), character) < 0) i++;
int i = indexOf(character);
if(i == chars.size() || Util.compareChars(chars.get(i), character) != 0) {
debugValues.increment(DEBUG_DELETIONS_DROPPED);
return -1;
}
chars.remove(i);
debugValues.increment(DEBUG_DELETIONS);
return i;

View File

@ -0,0 +1,95 @@
package me.mrletsplay.shareclientcore;
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
import static org.junit.jupiter.api.Assertions.assertEquals;
import java.util.Collections;
import java.util.List;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;
import me.mrletsplay.shareclientcore.document.ArrayCharBag;
import me.mrletsplay.shareclientcore.document.Char;
import me.mrletsplay.shareclientcore.document.CharBag;
import me.mrletsplay.shareclientcore.document.Identifier;
public class CharBagTest {
private CharBag createBag(Class<? extends CharBag> bagClass) {
return assertDoesNotThrow(() -> bagClass.getDeclaredConstructor().newInstance());
}
@ParameterizedTest
@ValueSource(classes = { ArrayCharBag.class })
public void testCharBagAdd(Class<? extends CharBag> bagClass) {
CharBag bag = createBag(bagClass);
Char c = new Char(new Identifier[] { new Identifier(0, 0) }, 0, (byte) 0);
assertEquals(0, bag.add(c));
assertEquals(List.of(c), bag.toList());
}
@ParameterizedTest
@ValueSource(classes = { ArrayCharBag.class })
public void testCharBagAddBetween(Class<? extends CharBag> bagClass) {
CharBag bag = createBag(bagClass);
Char c = new Char(new Identifier[] { new Identifier(0, 0) }, 0, (byte) 0);
Char c2 = new Char(new Identifier[] { new Identifier(1, 0) }, 1, (byte) 0);
Char cBetween = new Char(new Identifier[] { new Identifier(0, 1) }, 2, (byte) 0);
bag.add(c);
bag.add(c2);
assertEquals(List.of(c, c2), bag.toList());
assertEquals(1, bag.add(cBetween));
assertEquals(List.of(c, cBetween, c2), bag.toList());
}
@ParameterizedTest
@ValueSource(classes = { ArrayCharBag.class })
public void testCharBagRemove(Class<? extends CharBag> bagClass) {
CharBag bag = createBag(bagClass);
Char c = new Char(new Identifier[] { new Identifier(0, 0) }, 0, (byte) 0);
bag.add(c);
assertEquals(0, bag.remove(c));
assertEquals(Collections.emptyList(), bag.toList());
}
@ParameterizedTest
@ValueSource(classes = { ArrayCharBag.class })
public void testCharBagGet(Class<? extends CharBag> bagClass) {
CharBag bag = createBag(bagClass);
Char c = new Char(new Identifier[] { new Identifier(0, 0) }, 0, (byte) 0);
Char c2 = new Char(new Identifier[] { new Identifier(0, 1) }, 2, (byte) 0);
Char c3 = new Char(new Identifier[] { new Identifier(1, 0) }, 1, (byte) 0);
bag.add(c);
bag.add(c3);
bag.add(c2);
assertEquals(List.of(c, c2, c3), bag.toList());
assertEquals(c2, bag.get(1));
}
@ParameterizedTest
@ValueSource(classes = { ArrayCharBag.class })
public void testCharBagClear(Class<? extends CharBag> bagClass) {
CharBag bag = createBag(bagClass);
Char c = new Char(new Identifier[] { new Identifier(0, 0) }, 0, (byte) 0);
Char c2 = new Char(new Identifier[] { new Identifier(0, 1) }, 2, (byte) 0);
Char c3 = new Char(new Identifier[] { new Identifier(1, 0) }, 1, (byte) 0);
bag.add(c);
bag.add(c3);
bag.add(c2);
assertEquals(List.of(c, c2, c3), bag.toList());
bag.clear();
assertEquals(Collections.emptyList(), bag.toList());
}
}