/** Add a new tag to the set. */ ArrayTagSet add(String k, String v) { return add(new BasicTag(k, v)); }
/** Add a collection of tags to the set. */ ArrayTagSet addAll(Tag[] ts, int tsLength) { if (tsLength == 0) { return this; } else if (length == 0) { Arrays.sort(ts, 0, tsLength, TAG_COMPARATOR); int len = dedup(ts, 0, ts, 0, tsLength); return new ArrayTagSet(toStringArray(ts, len)); } else { String[] newTags = new String[(length + tsLength) * 2]; Arrays.sort(ts, 0, tsLength, TAG_COMPARATOR); int newLength = merge(newTags, tags, length, ts, tsLength); return new ArrayTagSet(newTags, newLength); } }
/** Create a new tag set. */ static ArrayTagSet create(Map<String, String> tags) { return EMPTY.addAll(tags); }
@Override public Id createId(String name, Iterable<Tag> tags) { return new DefaultId(name, ArrayTagSet.create(tags)); }
@Test public void testToString() { ArrayTagSet ts1 = ArrayTagSet.create("k1", "v1"); ArrayTagSet ts2 = ArrayTagSet.create("k2", "v2").addAll(ts1); ArrayTagSet ts3 = ArrayTagSet.create("k3", "v3").addAll(ts2); Assertions.assertEquals(":k1=v1", ts1.toString()); Assertions.assertEquals(":k1=v1:k2=v2", ts2.toString()); Assertions.assertEquals(":k1=v1:k2=v2:k3=v3", ts3.toString()); }
@Test public void addAllDedupMerge() { ArrayTagSet ts = ArrayTagSet.EMPTY .addAll(new String[] {"a", "1", "a", "2", "a", "3"}) .addAll(new String[] {"a", "4", "a", "5", "a", "6", "b", "1"}); ArrayTagSet expected = ArrayTagSet.EMPTY .add(new BasicTag("a", "6")) .add(new BasicTag("b", "1")); Assertions.assertEquals(expected, ts); } }
/** * Create a new id by possibly removing tags from the list. This operation will:<br/> * 1) remove keys as specified by the parameters<br/> * 2) dedup entries that have the same key, the first value associated with the key will be the one kept,<br/> * 3) sort the list by the tag keys. * * @param keys * Set of keys to either keep or remove. * @param keep * If true, then the new id can only have tag keys in the provided set. Otherwise the new id * can only have ids not in that set. * @return * New identifier after applying the rollup. */ DefaultId rollup(Set<String> keys, boolean keep) { if (tags.isEmpty()) { return this; } else { Map<String, String> ts = new TreeMap<>(); for (Tag t : tags) { if (keys.contains(t.key()) == keep && !ts.containsKey(t.key())) { ts.put(t.key(), t.value()); } } return new DefaultId(name, ArrayTagSet.create(ts)); } }
@Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null || !(obj instanceof DefaultId)) return false; DefaultId other = (DefaultId) obj; return name.equals(other.name) && tags.equals(other.tags); }
@Override public int hashCode() { int result = name.hashCode(); result = 31 * result + tags.hashCode(); return result; }
/** * Returns the size of an iterable. This method should only be used with fixed size * collections. It will attempt to find an efficient method to get the size before falling * back to a traversal of the iterable. */ @SuppressWarnings("PMD.UnusedLocalVariable") public static <T> int size(Iterable<T> iter) { if (iter instanceof ArrayTagSet) { return ((ArrayTagSet) iter).size(); } else if (iter instanceof Collection<?>) { return ((Collection<?>) iter).size(); } else { int size = 0; for (T v : iter) { ++size; } return size; } }
/** Add a new tag to the set. */ @SuppressWarnings("PMD.AvoidArrayLoops") ArrayTagSet add(Tag tag) { if (length == 0) { return new ArrayTagSet(new String[] {tag.key(), tag.value()}); } else { String[] newTags = new String[length + 2]; String k = tag.key(); int i = 0; for (; i < length && tags[i].compareTo(k) < 0; i += 2) { newTags[i] = tags[i]; newTags[i + 1] = tags[i + 1]; } if (i < length && tags[i].equals(k)) { // Override newTags[i++] = tag.key(); newTags[i++] = tag.value(); System.arraycopy(tags, i, newTags, i, length - i); i = length; } else { // Insert newTags[i] = tag.key(); newTags[i + 1] = tag.value(); System.arraycopy(tags, i, newTags, i + 2, length - i); i = newTags.length; } return new ArrayTagSet(newTags, i); } }
i += lengthA - ai; } else if (bi < lengthB) { i = dedup(srcB, bi, dst, i, lengthB - bi);
/** Create a new tag set. */ static ArrayTagSet create(Tag... tags) { return EMPTY.addAll(tags); }
@Override public final Id createId(String name, Iterable<Tag> tags) { return new DefaultId(name, ArrayTagSet.create(tags)); }
/** * Create a new id by possibly removing tags from the list. This operation will:<br/> * 1) remove keys as specified by the parameters<br/> * 2) dedup entries that have the same key, the first value associated with the key will be the one kept,<br/> * 3) sort the list by the tag keys. * * @param keys * Set of keys to either keep or remove. * @param keep * If true, then the new id can only have tag keys in the provided set. Otherwise the new id * can only have ids not in that set. * @return * New identifier after applying the rollup. */ DefaultId rollup(Set<String> keys, boolean keep) { if (tags.isEmpty()) { return this; } else { Map<String, String> ts = new TreeMap<>(); for (Tag t : tags) { if (keys.contains(t.key()) == keep && !ts.containsKey(t.key())) { ts.put(t.key(), t.value()); } } return new DefaultId(name, ArrayTagSet.create(ts)); } }