Skip to content

Commit 0b499b8

Browse files
authored
Fixes bad partitioning of data in the v1 memory store (openzipkin#1843)
*Note* this only affects people using the v1 in-memory component. The in-memory option of zipkin-server does not use this even if v1 format is accepted. This fixes a partitioning messup where all spans for the same timestamp filed under the same key.
1 parent e35065e commit 0b499b8

File tree

3 files changed

+28
-2
lines changed

3 files changed

+28
-2
lines changed

zipkin/src/main/java/zipkin/storage/InMemorySpanStore.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -330,7 +330,11 @@ static final class LinkedListSortedMultimap<K, V> extends SortedMultimap<K, V> {
330330
@Override public int compare(Pair<Long> left, Pair<Long> right) {
331331
long x = left._2, y = right._2;
332332
int result = (x < y) ? -1 : ((x == y) ? 0 : 1); // Long.compareTo is JRE 7+
333-
return -result; // use negative as we are descending
333+
if (result != 0) return -result; // use negative as we are descending
334+
// secondary compare as TreeMap is in use
335+
x = left._1;
336+
y = right._1;
337+
return (x < y) ? -1 : ((x == y) ? 0 : 1);
334338
}
335339

336340
@Override public String toString() {

zipkin/src/test/java/zipkin/storage/InMemorySpanStoreEvictionTest.java renamed to zipkin/src/test/java/zipkin/storage/InMemorySpanStoreTest.java

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
*/
1414
package zipkin.storage;
1515

16+
import java.util.Map;
1617
import org.junit.Before;
1718
import org.junit.Test;
1819
import zipkin.Annotation;
@@ -24,7 +25,7 @@
2425
import static org.assertj.core.api.Assertions.assertThat;
2526
import static zipkin.TestObjects.TODAY;
2627

27-
public class InMemorySpanStoreEvictionTest {
28+
public class InMemorySpanStoreTest {
2829
InMemoryStorage storage = new InMemoryStorage.Builder().maxSpanCount(1000).build();
2930
InMemorySpanStore store = storage.spanStore();
3031
StorageAdapters.SpanConsumer consumer = store.spanConsumer;
@@ -78,6 +79,16 @@ public void clear() {
7879
.id(0x654)
7980
.annotations(asList(ann7, ann8)).build();
8081

82+
/** Ensures we don't overload a partition due to key equality being conflated with order */
83+
@Test
84+
public void differentiatesOnTraceIdWhenTimestampEqual() {
85+
consumer.accept(asList(span1));
86+
consumer.accept(asList(span1.toBuilder().traceId(333L).build()));
87+
88+
assertThat(store).extracting("spansByTraceIdTimeStamp.delegate")
89+
.allSatisfy(map -> assertThat((Map) map).hasSize(2));
90+
}
91+
8192
@Test
8293
public void dropsLargerThanMax() {
8394
consumer.accept(asList(TestObjects.LOTS_OF_SPANS));

zipkin2/src/test/java/zipkin2/storage/InMemoryStorageTest.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
import java.io.IOException;
1717
import java.util.Collections;
1818
import java.util.List;
19+
import java.util.Map;
1920
import java.util.stream.Collectors;
2021
import java.util.stream.IntStream;
2122
import org.junit.Test;
@@ -27,6 +28,7 @@
2728
import static java.util.Arrays.asList;
2829
import static java.util.stream.Collectors.toList;
2930
import static org.assertj.core.api.Assertions.assertThat;
31+
import static zipkin2.TestObjects.CLIENT_SPAN;
3032
import static zipkin2.TestObjects.TODAY;
3133

3234
public class InMemoryStorageTest {
@@ -77,6 +79,15 @@ public class InMemoryStorageTest {
7779
.containsExactly(earlyTraces);
7880
}
7981

82+
/** Ensures we don't overload a partition due to key equality being conflated with order */
83+
@Test public void differentiatesOnTraceIdWhenTimestampEqual() {
84+
storage.accept(asList(CLIENT_SPAN));
85+
storage.accept(asList(CLIENT_SPAN.toBuilder().traceId("333").build()));
86+
87+
assertThat(storage).extracting("spansByTraceIdTimeStamp.delegate")
88+
.allSatisfy(map -> assertThat((Map) map).hasSize(2));
89+
}
90+
8091
/** It should be safe to run dependency link jobs twice */
8192
@Test public void replayOverwrites() throws IOException {
8293
Span span = Span.newBuilder().traceId("10").id("10").name("receive")

0 commit comments

Comments
 (0)