Fully implement generatePositionBetween, Add javadoc & source
This commit is contained in:
parent
93845890c1
commit
da2cd43ebf
39
pom.xml
39
pom.xml
@ -9,11 +9,48 @@
|
||||
<plugins>
|
||||
<plugin>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>3.8.1</version>
|
||||
<version>3.11.0</version>
|
||||
<configuration>
|
||||
<release>17</release>
|
||||
<encoding>UTF-8</encoding>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-jar-plugin</artifactId>
|
||||
<version>3.3.0</version>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-javadoc-plugin</artifactId>
|
||||
<version>3.6.2</version>
|
||||
<configuration>
|
||||
<source>17</source>
|
||||
<encoding>UTF-8</encoding>
|
||||
<sourcepath>src/main/java</sourcepath>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>attach-javadocs</id>
|
||||
<goals>
|
||||
<goal>jar</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-source-plugin</artifactId>
|
||||
<version>3.3.0</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>attach-sources</id>
|
||||
<goals>
|
||||
<goal>jar</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
|
@ -5,6 +5,8 @@ import java.util.List;
|
||||
|
||||
public class Util {
|
||||
|
||||
// Source for a lot of the code: https://digitalfreepen.com/2017/10/06/simple-real-time-collaborative-text-editor.html
|
||||
|
||||
public static final int BASE = 10;
|
||||
|
||||
public static int comparePositions(Identifier[] a, Identifier[] b) {
|
||||
@ -17,14 +19,17 @@ public class Util {
|
||||
}
|
||||
|
||||
public static Identifier[] generatePositionBetween(Identifier[] before, Identifier[] after, int site) {
|
||||
if(comparePositions(before, after) != -1) throw new IllegalArgumentException("before must be strictly less than after");
|
||||
|
||||
List<Identifier> newPosition = new ArrayList<>();
|
||||
|
||||
for(int i = 0; i < Math.min(before.length, after.length) + 1; i++) {
|
||||
Identifier c1 = i >= before.length ? new Identifier(0, site) : before[i];
|
||||
Identifier c2 = i >= after.length ? new Identifier(BASE, site) : after[i];
|
||||
Identifier c2 = i >= after.length ? new Identifier(BASE - 1, site) : after[i];
|
||||
|
||||
if(c1.digit() != c2.digit()) {
|
||||
// TODO: generate delta, then pick a value between
|
||||
int[] incremented = getIncremented(before, after, i);
|
||||
return constructPosition(incremented, before, after, site);
|
||||
}
|
||||
|
||||
if(c1.site() == c2.site()) {
|
||||
@ -34,7 +39,8 @@ public class Util {
|
||||
|
||||
if(c1.site() < c2.site()) {
|
||||
// Anything starting with before will be sorted before after
|
||||
newPosition.add(new Identifier(BASE, site));
|
||||
newPosition.add(c1);
|
||||
newPosition.add(new Identifier(1, site));
|
||||
return newPosition.toArray(Identifier[]::new);
|
||||
}
|
||||
|
||||
@ -44,9 +50,9 @@ public class Util {
|
||||
return null;
|
||||
}
|
||||
|
||||
public static int[] getIncremented(Identifier[] i1, Identifier[] i2, int offset) {
|
||||
public static int[] getIncremented(Identifier[] before, Identifier[] after, int offset) {
|
||||
// TODO: can potentially be optimized by just calculating the index of the first non-zero digit (e.g. don't return array and discard it -> just return the index)
|
||||
int[] delta = subtract(i2, i1, offset);
|
||||
int[] delta = subtract(after, before, offset);
|
||||
int firstNonZero = 0;
|
||||
for(int i = 0; i < delta.length; i++) {
|
||||
if(delta[i] != 0) {
|
||||
@ -57,16 +63,38 @@ public class Util {
|
||||
|
||||
// Because of math, (firstNonZero + 1) >= i1.length (I think)
|
||||
// then make the array 1 longer so we have space for the increment (which is one order of magnitude smaller)
|
||||
int[] incremented = new int[firstNonZero + 2];
|
||||
int[] incremented = new int[offset + firstNonZero + 2];
|
||||
for(int i = 0; i < incremented.length; i++) {
|
||||
incremented[i] = i <= i1.length ? i1[i].digit() : 0;
|
||||
incremented[i] = i < before.length ? before[i].digit() : 0;
|
||||
}
|
||||
|
||||
add1AtIndex(incremented, firstNonZero + 1); // last digit might be zero, which is ambigious, inc again
|
||||
if(incremented[incremented.length - 1] == 0) add1AtIndex(incremented, firstNonZero + 1);
|
||||
add1AtIndex(incremented, offset + firstNonZero + 1); // last digit might be zero, which is ambigious, inc again
|
||||
if(incremented[incremented.length - 1] == 0) add1AtIndex(incremented, offset + firstNonZero + 1);
|
||||
return incremented;
|
||||
}
|
||||
|
||||
public static Identifier[] constructPosition(int[] num, Identifier[] before, Identifier[] after, int site) {
|
||||
// Implements rules according to constructPosition from https://inria.hal.science/inria-00432368/document
|
||||
|
||||
Identifier[] ident = new Identifier[num.length];
|
||||
|
||||
for(int i = 0; i < num.length; i++) {
|
||||
int digit = num[i];
|
||||
|
||||
if(i == num.length - 1) {
|
||||
ident[i] = new Identifier(digit, site);
|
||||
}else if(i < before.length && digit == before[i].digit()) {
|
||||
ident[i] = before[i];
|
||||
}else if(i < after.length && digit == after[i].digit()) {
|
||||
ident[i] = after[i];
|
||||
}else {
|
||||
ident[i] = new Identifier(digit, site);
|
||||
}
|
||||
}
|
||||
|
||||
return ident;
|
||||
}
|
||||
|
||||
/**
|
||||
* Subtract b from a, where a > b
|
||||
*/
|
||||
|
@ -12,58 +12,122 @@ public class DecimalTest {
|
||||
|
||||
@Test
|
||||
public void testSimpleSubtraction() {
|
||||
Identifier[] a = new Identifier[] { new Identifier(1, 0), new Identifier(2, 0), new Identifier(3, 0) };
|
||||
Identifier[] b = new Identifier[] { new Identifier(1, 0), new Identifier(1, 0), new Identifier(3, 0) };
|
||||
Identifier[] a = { new Identifier(1, 0), new Identifier(2, 0), new Identifier(3, 0) };
|
||||
Identifier[] b = { new Identifier(1, 0), new Identifier(1, 0), new Identifier(3, 0) };
|
||||
assertArrayEquals(new int[] { 0, 1, 0 }, Util.subtract(a, b, 0));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCarrySubtraction() {
|
||||
Identifier[] a = new Identifier[] { new Identifier(2, 0), new Identifier(0, 0), new Identifier(4, 0) };
|
||||
Identifier[] b = new Identifier[] { new Identifier(1, 0), new Identifier(0, 0), new Identifier(5, 0) };
|
||||
Identifier[] a = { new Identifier(2, 0), new Identifier(0, 0), new Identifier(4, 0) };
|
||||
Identifier[] b = { new Identifier(1, 0), new Identifier(0, 0), new Identifier(5, 0) };
|
||||
assertArrayEquals(new int[] { 0, Util.BASE - 1, Util.BASE - 1 }, Util.subtract(a, b, 0));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOffsetSubtraction() {
|
||||
Identifier[] a = new Identifier[] { new Identifier(1, 0), new Identifier(0, 0), new Identifier(5, 0) };
|
||||
Identifier[] b = new Identifier[] { new Identifier(1, 0), new Identifier(0, 0), new Identifier(4, 0) };
|
||||
Identifier[] a = { new Identifier(1, 0), new Identifier(0, 0), new Identifier(5, 0) };
|
||||
Identifier[] b = { new Identifier(1, 0), new Identifier(0, 0), new Identifier(4, 0) };
|
||||
assertArrayEquals(new int[] { 0, 1 }, Util.subtract(a, b, 1));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReversedInputFails() {
|
||||
Identifier[] a = new Identifier[] { new Identifier(1, 0), new Identifier(1, 0), new Identifier(3, 0) };
|
||||
Identifier[] b = new Identifier[] { new Identifier(1, 0), new Identifier(2, 0), new Identifier(3, 0) };
|
||||
Identifier[] a = { new Identifier(1, 0), new Identifier(1, 0), new Identifier(3, 0) };
|
||||
Identifier[] b = { new Identifier(1, 0), new Identifier(2, 0), new Identifier(3, 0) };
|
||||
assertThrows(RuntimeException.class, () -> Util.subtract(a, b, 0));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSimpleAdd1() {
|
||||
int[] a = new int[] { 0, 0 };
|
||||
int[] a = { 0, 0 };
|
||||
Util.add1AtIndex(a, 1);
|
||||
assertArrayEquals(new int[] { 0, 1 }, a);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCarryAdd1() {
|
||||
int[] a = new int[] { 0, Util.BASE - 1 };
|
||||
int[] a = { 0, Util.BASE - 1 };
|
||||
Util.add1AtIndex(a, 1);
|
||||
assertArrayEquals(new int[] { 1, 0 }, a);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCarryAdd1_2() {
|
||||
int[] a = new int[] { 0, Util.BASE - 1, Util.BASE - 1 };
|
||||
int[] a = { 0, Util.BASE - 1, Util.BASE - 1 };
|
||||
Util.add1AtIndex(a, 2);
|
||||
assertArrayEquals(new int[] { 1, 0, 0 }, a);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCarryAdd1_3() {
|
||||
int[] a = new int[] { 0, Util.BASE - 1, Util.BASE - 1 };
|
||||
int[] a = { 0, Util.BASE - 1, Util.BASE - 1 };
|
||||
Util.add1AtIndex(a, 1);
|
||||
assertArrayEquals(new int[] { 1, 0, Util.BASE - 1 }, a);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIncrement_1() {
|
||||
Identifier[] a = { new Identifier(1, 0), new Identifier(2, 0) };
|
||||
Identifier[] b = { new Identifier(1, 0), new Identifier(3, 0) };
|
||||
assertArrayEquals(new int[] { 1, 2, 1 }, Util.getIncremented(a, b, 1));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIncrement_2() {
|
||||
Identifier[] a = { new Identifier(1, 0), new Identifier(2, 0) };
|
||||
Identifier[] b = { new Identifier(1, 0), new Identifier(2, 0), new Identifier(Util.BASE - 1, 0) };
|
||||
assertArrayEquals(new int[] { 1, 2, 0, 1 }, Util.getIncremented(a, b, 1));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCarryIncrement() {
|
||||
Identifier[] a = { new Identifier(1, 0), new Identifier(2, 0), new Identifier(Util.BASE - 1, 0) };
|
||||
Identifier[] b = { new Identifier(1, 0), new Identifier(4, 0) };
|
||||
assertArrayEquals(new int[] { 1, 3, 1 }, Util.getIncremented(a, b, 1));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testConstructPosition_1() {
|
||||
Identifier[] a = { new Identifier(1, 0), new Identifier(2, 0), new Identifier(Util.BASE - 1, 0) };
|
||||
Identifier[] b = { new Identifier(1, 0), new Identifier(4, 0) };
|
||||
int[] newIdent = Util.getIncremented(a, b, 1);
|
||||
Identifier[] expected = { new Identifier(1, 0), new Identifier(3, 1), new Identifier(1, 1) };
|
||||
assertArrayEquals(expected, Util.constructPosition(newIdent, a, b, 1));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testConstructPosition_2() {
|
||||
Identifier[] a = { new Identifier(1, 0), new Identifier(2, 2), new Identifier(2, 2) };
|
||||
Identifier[] b = { new Identifier(1, 0), new Identifier(4, 1), new Identifier(3, 1) };
|
||||
int[] newIdent = Util.getIncremented(a, b, 1);
|
||||
Identifier[] expected = { new Identifier(1, 0), new Identifier(2, 2), new Identifier(3, 3) };
|
||||
assertArrayEquals(expected, Util.constructPosition(newIdent, a, b, 3));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGeneratePosition_1() {
|
||||
Identifier[] a = { new Identifier(1, 0), new Identifier(2, 1) };
|
||||
Identifier[] b = { new Identifier(1, 0), new Identifier(3, 2) };
|
||||
Identifier[] newIdent = Util.generatePositionBetween(a, b, 3);
|
||||
Identifier[] expected = { new Identifier(1, 0), new Identifier(2, 1), new Identifier(1, 3) };
|
||||
assertArrayEquals(expected, newIdent);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGeneratePosition_2() {
|
||||
Identifier[] a = { new Identifier(1, 0), new Identifier(2, 1) };
|
||||
Identifier[] b = { new Identifier(1, 0), new Identifier(2, 2) };
|
||||
Identifier[] newIdent = Util.generatePositionBetween(a, b, 3);
|
||||
Identifier[] expected = { new Identifier(1, 0), new Identifier(2, 1), new Identifier(1, 3) };
|
||||
assertArrayEquals(expected, newIdent);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGeneratePositionInvalidInputFails() {
|
||||
Identifier[] a = { new Identifier(1, 0), new Identifier(2, 2) };
|
||||
Identifier[] b = { new Identifier(1, 0), new Identifier(2, 1) };
|
||||
assertThrows(IllegalArgumentException.class, () -> Util.generatePositionBetween(a, b, 3));
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user