From 1651cf5b453a7a4990aba04def4ca4030da39eec Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?S=C3=B6ren=20Henning?= <soeren.henning@email.uni-kiel.de>
Date: Thu, 3 Mar 2022 09:24:18 +0100
Subject: [PATCH] Add support for more instances than keys

---
 .../benchmarks/loadgenerator/KeySpace.java    |  14 +-
 .../loadgenerator/WorkloadDefinition.java     |  10 +-
 .../loadgenerator/KeySpaceTest.java           |   4 +-
 .../loadgenerator/WorkloadDefinitionTest.java | 135 +++++++++++++++---
 4 files changed, 129 insertions(+), 34 deletions(-)

diff --git a/theodolite-benchmarks/load-generator-commons/src/main/java/rocks/theodolite/benchmarks/loadgenerator/KeySpace.java b/theodolite-benchmarks/load-generator-commons/src/main/java/rocks/theodolite/benchmarks/loadgenerator/KeySpace.java
index ed5d9a498..82dac7b42 100644
--- a/theodolite-benchmarks/load-generator-commons/src/main/java/rocks/theodolite/benchmarks/loadgenerator/KeySpace.java
+++ b/theodolite-benchmarks/load-generator-commons/src/main/java/rocks/theodolite/benchmarks/loadgenerator/KeySpace.java
@@ -10,7 +10,7 @@ import java.util.stream.IntStream;
  */
 public class KeySpace implements Serializable {
 
-  private static final long serialVersionUID = 7343135392720315515L; // NOPMD
+  private static final long serialVersionUID = 7343135392720315516L; // NOPMD
 
   private final String prefix;
   private final int min;
@@ -18,11 +18,11 @@ public class KeySpace implements Serializable {
 
   /**
    * Create a new key space. All keys will have the prefix {@code prefix}. The remaining part of
-   * each key will be determined by a number of the interval ({@code min}, {@code max}).
+   * each key will be determined by a number of the interval [{@code min}, {@code max}).
    *
    * @param prefix the prefix to use for all keys
    * @param min the lower bound (inclusive) to start counting from
-   * @param max the upper bound (inclusive) to count to
+   * @param max the upper bound (exclusive) to count to
    */
   public KeySpace(final String prefix, final int min, final int max) {
     this.prefix = prefix;
@@ -31,7 +31,7 @@ public class KeySpace implements Serializable {
   }
 
   public KeySpace(final String prefix, final int numberOfKeys) {
-    this(prefix, 0, numberOfKeys - 1);
+    this(prefix, 0, numberOfKeys);
   }
 
   public String getPrefix() {
@@ -52,21 +52,21 @@ public class KeySpace implements Serializable {
    * Get the amount of keys in this {@link KeySpace}.
    */
   public int getCount() {
-    return this.getMax() - this.getMin() + 1;
+    return this.max - this.min;
   }
 
   /**
    * Get all keys in this {@link KeySpace}.
    */
   public Collection<String> getKeys() {
-    return IntStream.rangeClosed(this.min, this.max)
+    return IntStream.range(this.min, this.max)
         .mapToObj(id -> this.prefix + id)
         .collect(Collectors.toUnmodifiableList());
   }
 
   @Override
   public String toString() {
-    return this.prefix + '[' + this.min + '-' + this.max + ']';
+    return this.prefix + '[' + this.min + '-' + this.max + ')';
   }
 
 }
diff --git a/theodolite-benchmarks/load-generator-commons/src/main/java/rocks/theodolite/benchmarks/loadgenerator/WorkloadDefinition.java b/theodolite-benchmarks/load-generator-commons/src/main/java/rocks/theodolite/benchmarks/loadgenerator/WorkloadDefinition.java
index 458997cce..1e7e6e597 100644
--- a/theodolite-benchmarks/load-generator-commons/src/main/java/rocks/theodolite/benchmarks/loadgenerator/WorkloadDefinition.java
+++ b/theodolite-benchmarks/load-generator-commons/src/main/java/rocks/theodolite/benchmarks/loadgenerator/WorkloadDefinition.java
@@ -42,16 +42,16 @@ public class WorkloadDefinition implements Serializable {
    * distributing its {@link KeySpace} (almost) equally among all {@link WorkloadDefinition}s.
    */
   public Set<WorkloadDefinition> divide(final int parts) {
-    final int effParts = Math.min(parts, this.keySpace.getCount());
-    final int minSize = this.keySpace.getCount() / effParts;
-    final int largerParts = this.keySpace.getCount() % effParts;
-    return IntStream.range(0, effParts)
+    // final int effParts = Math.min(parts, this.keySpace.getCount());
+    final int minSize = this.keySpace.getCount() / parts;
+    final int largerParts = this.keySpace.getCount() % parts;
+    return IntStream.range(0, parts)
         .mapToObj(part -> {
           final int thisSize = part < largerParts ? minSize + 1 : minSize;
           final int largePartsBefore = Math.min(largerParts, part);
           final int smallPartsBefore = part - largePartsBefore;
           final int start = largePartsBefore * (minSize + 1) + smallPartsBefore * minSize;
-          final int end = start + thisSize - 1;
+          final int end = start + thisSize;
           return new KeySpace(
               this.keySpace.getPrefix(),
               start,
diff --git a/theodolite-benchmarks/load-generator-commons/src/test/java/rocks/theodolite/benchmarks/loadgenerator/KeySpaceTest.java b/theodolite-benchmarks/load-generator-commons/src/test/java/rocks/theodolite/benchmarks/loadgenerator/KeySpaceTest.java
index 829f26ba4..cbd230433 100644
--- a/theodolite-benchmarks/load-generator-commons/src/test/java/rocks/theodolite/benchmarks/loadgenerator/KeySpaceTest.java
+++ b/theodolite-benchmarks/load-generator-commons/src/test/java/rocks/theodolite/benchmarks/loadgenerator/KeySpaceTest.java
@@ -7,14 +7,14 @@ public class KeySpaceTest {
 
   @Test
   public void testCountFixedRangeFromZero() {
-    final KeySpace keySpace = new KeySpace("prefix", 0, 9);
+    final KeySpace keySpace = new KeySpace("prefix", 0, 10);
     final int count = keySpace.getCount();
     Assert.assertEquals(10, count);
   }
 
   @Test
   public void testCountFixedRangeNotFromZero() {
-    final KeySpace keySpace = new KeySpace("prefix", 4, 11);
+    final KeySpace keySpace = new KeySpace("prefix", 4, 12);
     final int count = keySpace.getCount();
     Assert.assertEquals(8, count);
   }
diff --git a/theodolite-benchmarks/load-generator-commons/src/test/java/rocks/theodolite/benchmarks/loadgenerator/WorkloadDefinitionTest.java b/theodolite-benchmarks/load-generator-commons/src/test/java/rocks/theodolite/benchmarks/loadgenerator/WorkloadDefinitionTest.java
index fb10f36e0..b670a73c6 100644
--- a/theodolite-benchmarks/load-generator-commons/src/test/java/rocks/theodolite/benchmarks/loadgenerator/WorkloadDefinitionTest.java
+++ b/theodolite-benchmarks/load-generator-commons/src/test/java/rocks/theodolite/benchmarks/loadgenerator/WorkloadDefinitionTest.java
@@ -5,6 +5,7 @@ import java.util.Comparator;
 import java.util.List;
 import java.util.Set;
 import java.util.stream.Collectors;
+import java.util.stream.IntStream;
 import org.junit.Assert;
 import org.junit.Test;
 
@@ -47,15 +48,27 @@ public class WorkloadDefinitionTest {
     final List<WorkloadDefinition> orderedSubworkloads = subworkloads.stream()
         .sorted(Comparator.comparingInt(l -> l.getKeySpace().getMin()))
         .collect(Collectors.toList());
+
     final WorkloadDefinition subworkload1 = orderedSubworkloads.get(0);
-    Assert.assertEquals(0, subworkload1.getKeySpace().getMin());
-    Assert.assertEquals(33, subworkload1.getKeySpace().getMax());
+    final List<String> expectedKeySubworkload1 = IntStream
+        .rangeClosed(0, 33)
+        .mapToObj(id -> "prefix" + id)
+        .collect(Collectors.toList());
+    Assert.assertEquals(expectedKeySubworkload1, subworkload1.getKeySpace().getKeys());
+
     final WorkloadDefinition subworkload2 = orderedSubworkloads.get(1);
-    Assert.assertEquals(34, subworkload2.getKeySpace().getMin());
-    Assert.assertEquals(66, subworkload2.getKeySpace().getMax());
+    final List<String> expectedKeySubworkload2 = IntStream
+        .rangeClosed(34, 66)
+        .mapToObj(id -> "prefix" + id)
+        .collect(Collectors.toList());
+    Assert.assertEquals(expectedKeySubworkload2, subworkload2.getKeySpace().getKeys());
+
     final WorkloadDefinition subworkload3 = orderedSubworkloads.get(2);
-    Assert.assertEquals(67, subworkload3.getKeySpace().getMin());
-    Assert.assertEquals(99, subworkload3.getKeySpace().getMax());
+    final List<String> expectedKeySubworkload3 = IntStream
+        .rangeClosed(67, 99)
+        .mapToObj(id -> "prefix" + id)
+        .collect(Collectors.toList());
+    Assert.assertEquals(expectedKeySubworkload3, subworkload3.getKeySpace().getKeys());
   }
 
   @Test
@@ -71,27 +84,109 @@ public class WorkloadDefinitionTest {
     final List<WorkloadDefinition> orderedSubworkloads = subworkloads.stream()
         .sorted(Comparator.comparingInt(l -> l.getKeySpace().getMin()))
         .collect(Collectors.toList());
+
     final WorkloadDefinition subworkload1 = orderedSubworkloads.get(0);
-    Assert.assertEquals(0, subworkload1.getKeySpace().getMin());
-    Assert.assertEquals(1, subworkload1.getKeySpace().getMax());
+    final List<String> expectedKeySubworkload1 = IntStream
+        .rangeClosed(0, 1)
+        .mapToObj(id -> "prefix" + id)
+        .collect(Collectors.toList());
+    Assert.assertEquals(expectedKeySubworkload1, subworkload1.getKeySpace().getKeys());
+
     final WorkloadDefinition subworkload2 = orderedSubworkloads.get(1);
-    Assert.assertEquals(2, subworkload2.getKeySpace().getMin());
-    Assert.assertEquals(3, subworkload2.getKeySpace().getMax());
+    final List<String> expectedKeySubworkload2 = IntStream
+        .rangeClosed(2, 3)
+        .mapToObj(id -> "prefix" + id)
+        .collect(Collectors.toList());
+    Assert.assertEquals(expectedKeySubworkload2, subworkload2.getKeySpace().getKeys());
+
     final WorkloadDefinition subworkload3 = orderedSubworkloads.get(2);
-    Assert.assertEquals(4, subworkload3.getKeySpace().getMin());
-    Assert.assertEquals(5, subworkload3.getKeySpace().getMax());
+    final List<String> expectedKeySubworkload3 = IntStream
+        .rangeClosed(4, 5)
+        .mapToObj(id -> "prefix" + id)
+        .collect(Collectors.toList());
+    Assert.assertEquals(expectedKeySubworkload3, subworkload3.getKeySpace().getKeys());
+
     final WorkloadDefinition subworkload4 = orderedSubworkloads.get(3);
-    Assert.assertEquals(6, subworkload4.getKeySpace().getMin());
-    Assert.assertEquals(6, subworkload4.getKeySpace().getMax());
+    final List<String> expectedKeySubworkload4 = IntStream
+        .rangeClosed(6, 6)
+        .mapToObj(id -> "prefix" + id)
+        .collect(Collectors.toList());
+    Assert.assertEquals(expectedKeySubworkload4, subworkload4.getKeySpace().getKeys());
+
     final WorkloadDefinition subworkload5 = orderedSubworkloads.get(4);
-    Assert.assertEquals(7, subworkload5.getKeySpace().getMin());
-    Assert.assertEquals(7, subworkload5.getKeySpace().getMax());
+    final List<String> expectedKeySubworkload5 = IntStream
+        .rangeClosed(7, 7)
+        .mapToObj(id -> "prefix" + id)
+        .collect(Collectors.toList());
+    Assert.assertEquals(expectedKeySubworkload5, subworkload5.getKeySpace().getKeys());
+
     final WorkloadDefinition subworkload6 = orderedSubworkloads.get(5);
-    Assert.assertEquals(8, subworkload6.getKeySpace().getMin());
-    Assert.assertEquals(8, subworkload6.getKeySpace().getMax());
+    final List<String> expectedKeySubworkload6 = IntStream
+        .rangeClosed(8, 8)
+        .mapToObj(id -> "prefix" + id)
+        .collect(Collectors.toList());
+    Assert.assertEquals(expectedKeySubworkload6, subworkload6.getKeySpace().getKeys());
+
     final WorkloadDefinition subworkload7 = orderedSubworkloads.get(6);
-    Assert.assertEquals(9, subworkload7.getKeySpace().getMin());
-    Assert.assertEquals(9, subworkload7.getKeySpace().getMax());
+    final List<String> expectedKeySubworkload7 = IntStream
+        .rangeClosed(9, 9)
+        .mapToObj(id -> "prefix" + id)
+        .collect(Collectors.toList());
+    Assert.assertEquals(expectedKeySubworkload7, subworkload7.getKeySpace().getKeys());
+  }
+
+  @Test
+  public void testDivideWithOneEmpty() {
+    final KeySpace keySpace = new KeySpace("prefix", 2);
+    final WorkloadDefinition workload = new WorkloadDefinition(keySpace, Duration.ofSeconds(1));
+    final Set<WorkloadDefinition> subworkloads = workload.divide(3);
+    Assert.assertEquals(3, subworkloads.size());
+    for (final WorkloadDefinition subworkload : subworkloads) {
+      Assert.assertEquals("prefix", subworkload.getKeySpace().getPrefix());
+      Assert.assertEquals(Duration.ofSeconds(1), subworkload.getPeriod());
+    }
+    final List<WorkloadDefinition> orderedSubworkloads = subworkloads.stream()
+        .sorted(Comparator.comparingInt(l -> l.getKeySpace().getMin()))
+        .collect(Collectors.toList());
+
+    final WorkloadDefinition subworkload1 = orderedSubworkloads.get(0);
+    final List<String> expectedKeySubworkload1 = List.of("prefix0");
+    Assert.assertEquals(expectedKeySubworkload1, subworkload1.getKeySpace().getKeys());
+
+    final WorkloadDefinition subworkload2 = orderedSubworkloads.get(1);
+    final List<String> expectedKeySubworkload2 = List.of("prefix1");
+    Assert.assertEquals(expectedKeySubworkload2, subworkload2.getKeySpace().getKeys());
+
+    final WorkloadDefinition subworkload3 = orderedSubworkloads.get(2);
+    final List<String> expectedKeySubworkload3 = List.of();
+    Assert.assertEquals(expectedKeySubworkload3, subworkload3.getKeySpace().getKeys());
+  }
+
+  @Test
+  public void testDivideWithTwoEmpty() {
+    final KeySpace keySpace = new KeySpace("prefix", 1);
+    final WorkloadDefinition workload = new WorkloadDefinition(keySpace, Duration.ofSeconds(1));
+    final Set<WorkloadDefinition> subworkloads = workload.divide(3);
+    Assert.assertEquals(3, subworkloads.size());
+    for (final WorkloadDefinition subworkload : subworkloads) {
+      Assert.assertEquals("prefix", subworkload.getKeySpace().getPrefix());
+      Assert.assertEquals(Duration.ofSeconds(1), subworkload.getPeriod());
+    }
+    final List<WorkloadDefinition> orderedSubworkloads = subworkloads.stream()
+        .sorted(Comparator.comparingInt(l -> l.getKeySpace().getMin()))
+        .collect(Collectors.toList());
+
+    final WorkloadDefinition subworkload1 = orderedSubworkloads.get(0);
+    final List<String> expectedKeySubworkload1 = List.of("prefix0");
+    Assert.assertEquals(expectedKeySubworkload1, subworkload1.getKeySpace().getKeys());
+
+    final WorkloadDefinition subworkload2 = orderedSubworkloads.get(1);
+    final List<String> expectedKeySubworkload2 = List.of();
+    Assert.assertEquals(expectedKeySubworkload2, subworkload2.getKeySpace().getKeys());
+
+    final WorkloadDefinition subworkload3 = orderedSubworkloads.get(2);
+    final List<String> expectedKeySubworkload3 = List.of();
+    Assert.assertEquals(expectedKeySubworkload3, subworkload3.getKeySpace().getKeys());
   }
 
 }
-- 
GitLab