Github user ifesdjeen commented on a diff in the pull request: https://github.com/apache/cassandra/pull/271#discussion_r220986153 --- Diff: src/java/org/apache/cassandra/locator/AbstractReplicaCollection.java --- @@ -58,45 +63,332 @@ }; } - protected final List<Replica> list; - protected final boolean isSnapshot; - protected AbstractReplicaCollection(List<Replica> list, boolean isSnapshot) + /** + * A simple list with no comodification checks and immutability by default (only append permitted, and only one initial copy) + * this permits us to reduce the amount of garbage generated, by not wrapping iterators or unnecessarily copying + * and reduces the amount of indirection necessary, as well as ensuring monomorphic callsites + */ + protected static class ReplicaList implements Iterable<Replica> { - this.list = list; - this.isSnapshot = isSnapshot; + private static final Replica[] EMPTY = new Replica[0]; + Replica[] contents; + int begin, size; + + public ReplicaList() { this(0); } + public ReplicaList(int capacity) { contents = capacity == 0 ? EMPTY : new Replica[capacity]; } + public ReplicaList(Replica[] contents, int begin, int size) { this.contents = contents; this.begin = begin; this.size = size; } + + public boolean isSubList(ReplicaList subList) + { + return subList.contents == contents; + } + + public Replica get(int index) + { + if (index > size) + throw new IndexOutOfBoundsException(); + return contents[begin + index]; + } + + public void add(Replica replica) + { + // can only add to full array - if we have sliced it, we must be a snapshot + assert begin == 0; + if (size == contents.length) + { + int newSize; + if (size < 3) newSize = 3; + else if (size < 9) newSize = 9; + else newSize = size * 2; + contents = Arrays.copyOf(contents, newSize); + } + contents[size++] = replica; + } + + public int size() + { + return size; + } + + public boolean isEmpty() + { + return size == 0; + } + + public ReplicaList subList(int begin, int end) + { + if (end > size || begin > end) throw new IndexOutOfBoundsException(); + return new ReplicaList(contents, this.begin + begin, end - begin); + } + + public ReplicaList sorted(Comparator<Replica> comparator) + { + Replica[] copy = Arrays.copyOfRange(contents, begin, begin + size); + Arrays.sort(copy, comparator); + return new ReplicaList(copy, 0, copy.length); + } + + public Stream<Replica> stream() + { + return Arrays.stream(contents, begin, begin + size); + } + + @Override + public Iterator<Replica> iterator() + { + return new Iterator<Replica>() + { + final int end = begin + size; + int i = begin; + @Override + public boolean hasNext() + { + return i < end; + } + + @Override + public Replica next() + { + return contents[i++]; + } + }; + } + + public <K> Iterator<K> transformIterator(Function<Replica, K> function) + { + return new Iterator<K>() + { + final int end = begin + size; + int i = begin; + @Override + public boolean hasNext() + { + return i < end; + } + + @Override + public K next() + { + return function.apply(contents[i++]); + } + }; + } + + private Iterator<Replica> filterIterator(Predicate<Replica> predicate, int limit) + { + return new Iterator<Replica>() --- End diff -- Sure, if this was a deliberate decision, I have nothing against it.
--- --------------------------------------------------------------------- To unsubscribe, e-mail: pr-unsubscr...@cassandra.apache.org For additional commands, e-mail: pr-h...@cassandra.apache.org