Skip to content

Commit

Permalink
Merge branch '1.14.x'
Browse files Browse the repository at this point in the history
  • Loading branch information
jonatan-ivanov committed Nov 21, 2024
2 parents 311efdb + 157b656 commit be70882
Show file tree
Hide file tree
Showing 6 changed files with 106 additions and 89 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ public class KeyValuesMergeBenchmark {

static final KeyValues left = KeyValues.of("key", "value", "key2", "value2", "key6", "value6", "key7", "value7",
"key8", "value8", "keyA", "valueA", "keyC", "valueC", "keyE", "valueE", "keyF", "valueF", "keyG", "valueG",
"keyG", "valueG", "keyG", "valueG", "keyH", "valueH");
"keyH", "valueH");

static final KeyValues right = KeyValues.of("key", "value", "key1", "value1", "key2", "value2", "key3", "value3",
"key4", "value4", "key5", "value5", "keyA", "valueA", "keyB", "valueB", "keyD", "valueD");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,8 @@
public class TagsMergeBenchmark {

static final Tags left = Tags.of("key", "value", "key2", "value2", "key6", "value6", "key7", "value7", "key8",
"value8", "keyA", "valueA", "keyC", "valueC", "keyE", "valueE", "keyF", "valueF", "keyG", "valueG", "keyG",
"valueG", "keyG", "valueG", "keyH", "valueH");
"value8", "keyA", "valueA", "keyC", "valueC", "keyE", "valueE", "keyF", "valueF", "keyG", "valueG", "keyH",
"valueH");

static final Tags right = Tags.of("key", "value", "key1", "value1", "key2", "value2", "key3", "value3", "key4",
"value4", "key5", "value5", "keyA", "valueA", "keyB", "valueB", "keyD", "valueD");
Expand Down
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -432,7 +432,7 @@ nexusPublishing {
}

wrapper {
gradleVersion = '8.11'
gradleVersion = '8.11.1'
}

defaultTasks 'build'
2 changes: 1 addition & 1 deletion gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.11-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.11.1-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
Expand Down
113 changes: 61 additions & 52 deletions micrometer-commons/src/main/java/io/micrometer/common/KeyValues.java
Original file line number Diff line number Diff line change
Expand Up @@ -36,37 +36,39 @@
*/
public final class KeyValues implements Iterable<KeyValue> {

private static final KeyValues EMPTY = new KeyValues(new KeyValue[] {}, 0);
private static final KeyValue[] EMPTY_KEY_VALUE_ARRAY = new KeyValue[0];

private static final KeyValues EMPTY = new KeyValues(EMPTY_KEY_VALUE_ARRAY, 0);

/**
* A private array of {@code KeyValue} objects containing the sorted and deduplicated
* tags.
* An array of {@code KeyValue} objects containing the sorted and deduplicated
* key-values.
*/
private final KeyValue[] sortedSet;

/**
* The number of valid tags present in the {@link #sortedSet} array.
* The number of valid key-values present in the {@link #sortedSet} array.
*/
private final int length;

/**
* A private constructor that initializes a {@code KeyValues} object with a sorted set
* of keyvalues and its length.
* @param sortedSet an ordered set of unique keyvalues by key
* @param length the number of valid tags in the {@code sortedSet}
* A constructor that initializes a {@code KeyValues} object with a sorted set of
* key-values and its length.
* @param sortedSet an ordered set of unique key-values by key
* @param length the number of valid key-values in the {@code sortedSet}
*/
private KeyValues(KeyValue[] sortedSet, int length) {
this.sortedSet = sortedSet;
this.length = length;
}

/**
* Checks if the first {@code length} elements of the {@code keyvalues} array form an
* ordered set of keyvalues.
* @param keyValues an array of keyvalues.
* @param length the number of items to check.
* @return {@code true} if the first {@code length} items of {@code keyvalues} form an
* ordered set; otherwise {@code false}.
* Checks if the first {@code length} elements of the {@code keyValues} array form an
* ordered set of key-values.
* @param keyValues an array of key-values.
* @param length the number of elements to check.
* @return {@code true} if the first {@code length} elements of {@code keyValues} form
* an ordered set; otherwise {@code false}.
*/
private static boolean isSortedSet(KeyValue[] keyValues, int length) {
if (length > keyValues.length) {
Expand All @@ -82,12 +84,13 @@ private static boolean isSortedSet(KeyValue[] keyValues, int length) {
}

/**
* Constructs a {@code Tags} collection from the provided array of tags.
* @param keyValues an array of {@code Tag} objects, possibly unordered and/or
* Constructs a {@code KeyValues} collection from the provided array of key-values.
* @param keyValues an array of {@code KeyValue} objects, possibly unordered and/or
* containing duplicates.
* @return a {@code Tags} instance with a deduplicated and ordered set of tags.
* @return a {@code KeyValues} instance with a deduplicated and ordered set of
* key-values.
*/
private static KeyValues make(KeyValue[] keyValues) {
private static KeyValues toKeyValues(KeyValue[] keyValues) {
int len = keyValues.length;
if (!isSortedSet(keyValues, len)) {
Arrays.sort(keyValues);
Expand All @@ -97,10 +100,10 @@ private static KeyValues make(KeyValue[] keyValues) {
}

/**
* Removes duplicate tags from an ordered array of tags.
* @param keyValues an ordered array of {@code Tag} objects.
* @return the number of unique tags in the {@code tags} array after removing
* duplicates.
* Removes duplicate key-values from an ordered array of key-values.
* @param keyValues an ordered array of {@code KeyValue} objects.
* @return the number of unique key-values in the {@code keyValues} array after
* removing duplicates.
*/
private static int dedup(KeyValue[] keyValues) {
int n = keyValues.length;
Expand All @@ -121,49 +124,55 @@ private static int dedup(KeyValue[] keyValues) {
}

/**
* Constructs a {@code Tags} instance by merging two sets of tags in time proportional
* to the sum of their sizes.
* @param other the set of tags to merge with this one.
* @return a {@code Tags} instance with the merged sets of tags.
* Constructs a {@code KeyValues} instance by merging two sets of key-values in time
* proportional to the sum of their sizes.
* @param other the set of key-values to merge with this one.
* @return a {@code KeyValues} instance with the merged sets of key-values.
*/
private KeyValues merged(KeyValues other) {
private KeyValues merge(KeyValues other) {
if (other.length == 0) {
return this;
}
if (Objects.equals(this, other)) {
return this;
}
KeyValue[] sortedSet = new KeyValue[this.length + other.length];
int sortedIdx = 0, thisIdx = 0, otherIdx = 0;
while (thisIdx < this.length && otherIdx < other.length) {
int cmp = this.sortedSet[thisIdx].compareTo(other.sortedSet[otherIdx]);
int sortedIndex = 0;
int thisIndex = 0;
int otherIndex = 0;
while (thisIndex < this.length && otherIndex < other.length) {
KeyValue thisKeyValue = this.sortedSet[thisIndex];
KeyValue otherKeyValue = other.sortedSet[otherIndex];
int cmp = thisKeyValue.compareTo(otherKeyValue);
if (cmp > 0) {
sortedSet[sortedIdx] = other.sortedSet[otherIdx];
otherIdx++;
sortedSet[sortedIndex] = otherKeyValue;
otherIndex++;
}
else if (cmp < 0) {
sortedSet[sortedIdx] = this.sortedSet[thisIdx];
thisIdx++;
sortedSet[sortedIndex] = thisKeyValue;
thisIndex++;
}
else {
// In case of key conflict prefer tag from other set
sortedSet[sortedIdx] = other.sortedSet[otherIdx];
thisIdx++;
otherIdx++;
// In case of key conflict prefer key-value from other set
sortedSet[sortedIndex] = otherKeyValue;
thisIndex++;
otherIndex++;
}
sortedIdx++;
sortedIndex++;
}
int thisRemaining = this.length - thisIdx;
int thisRemaining = this.length - thisIndex;
if (thisRemaining > 0) {
System.arraycopy(this.sortedSet, thisIdx, sortedSet, sortedIdx, thisRemaining);
sortedIdx += thisRemaining;
System.arraycopy(this.sortedSet, thisIndex, sortedSet, sortedIndex, thisRemaining);
sortedIndex += thisRemaining;
}
int otherRemaining = other.length - otherIdx;
if (otherIdx < other.sortedSet.length) {
System.arraycopy(other.sortedSet, otherIdx, sortedSet, sortedIdx, otherRemaining);
sortedIdx += otherRemaining;
else {
int otherRemaining = other.length - otherIndex;
if (otherRemaining > 0) {
System.arraycopy(other.sortedSet, otherIndex, sortedSet, sortedIndex, otherRemaining);
sortedIndex += otherRemaining;
}
}
return new KeyValues(sortedSet, sortedIdx);
return new KeyValues(sortedSet, sortedIndex);
}

/**
Expand Down Expand Up @@ -200,7 +209,7 @@ public KeyValues and(@Nullable KeyValue... keyValues) {
if (blankVarargs(keyValues)) {
return this;
}
return and(make(keyValues));
return and(toKeyValues(keyValues));
}

/**
Expand Down Expand Up @@ -237,7 +246,7 @@ public KeyValues and(@Nullable Iterable<? extends KeyValue> keyValues) {
return KeyValues.of(keyValues);
}

return merged(KeyValues.of(keyValues));
return merge(KeyValues.of(keyValues));
}

@Override
Expand Down Expand Up @@ -362,10 +371,10 @@ else if (keyValues instanceof KeyValues) {
}
else if (keyValues instanceof Collection) {
Collection<? extends KeyValue> keyValuesCollection = (Collection<? extends KeyValue>) keyValues;
return make(keyValuesCollection.toArray(new KeyValue[0]));
return toKeyValues(keyValuesCollection.toArray(EMPTY_KEY_VALUE_ARRAY));
}
else {
return make(StreamSupport.stream(keyValues.spliterator(), false).toArray(KeyValue[]::new));
return toKeyValues(StreamSupport.stream(keyValues.spliterator(), false).toArray(KeyValue[]::new));
}
}

Expand Down Expand Up @@ -397,7 +406,7 @@ public static KeyValues of(@Nullable String... keyValues) {
for (int i = 0; i < keyValues.length; i += 2) {
keyValueArray[i / 2] = KeyValue.of(keyValues[i], keyValues[i + 1]);
}
return make(keyValueArray);
return toKeyValues(keyValueArray);
}

private static boolean blankVarargs(@Nullable Object[] args) {
Expand Down
Loading

0 comments on commit be70882

Please sign in to comment.