/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.cassandra.utils.btree; import java.util.Arrays; import java.util.Collection; import java.util.Comparator; import java.util.Iterator; import java.util.NavigableSet; import java.util.SortedSet; public class BTreeSet<V> implements NavigableSet<V> { protected final Comparator<V> comparator; protected final Object[] tree; public BTreeSet(Object[] tree, Comparator<V> comparator) { this.tree = tree; this.comparator = comparator; } public BTreeSet<V> update(Collection<V> updateWith, boolean isSorted) { return new BTreeSet<>(BTree.update(tree, comparator, updateWith, isSorted, UpdateFunction.NoOp.<V>instance()), comparator); } @Override public Comparator<? super V> comparator() { return comparator; } protected Cursor<V, V> slice(boolean forwards, boolean permitInversion) { return BTree.slice(tree, forwards); } @Override public int size() { return slice(true, false).count(); } @Override public boolean isEmpty() { return slice(true, false).hasNext(); } @Override public Iterator<V> iterator() { return slice(true, true); } @Override public Iterator<V> descendingIterator() { return slice(false, true); } @Override public Object[] toArray() { return toArray(new Object[0]); } @Override public <T> T[] toArray(T[] a) { int size = size(); if (a.length < size) a = Arrays.copyOf(a, size); int i = 0; for (V v : this) a[i++] = (T) v; return a; } @Override public NavigableSet<V> subSet(V fromElement, boolean fromInclusive, V toElement, boolean toInclusive) { return new BTreeRange<>(tree, comparator, fromElement, fromInclusive, toElement, toInclusive); } @Override public NavigableSet<V> headSet(V toElement, boolean inclusive) { return new BTreeRange<>(tree, comparator, null, true, toElement, inclusive); } @Override public NavigableSet<V> tailSet(V fromElement, boolean inclusive) { return new BTreeRange<>(tree, comparator, fromElement, inclusive, null, true); } @Override public SortedSet<V> subSet(V fromElement, V toElement) { return subSet(fromElement, true, toElement, false); } @Override public SortedSet<V> headSet(V toElement) { return headSet(toElement, false); } @Override public SortedSet<V> tailSet(V fromElement) { return tailSet(fromElement, true); } @Override public V first() { throw new UnsupportedOperationException(); } @Override public V last() { throw new UnsupportedOperationException(); } @Override public boolean addAll(Collection<? extends V> c) { throw new UnsupportedOperationException(); } @Override public boolean retainAll(Collection<?> c) { throw new UnsupportedOperationException(); } @Override public boolean removeAll(Collection<?> c) { throw new UnsupportedOperationException(); } @Override public void clear() { throw new UnsupportedOperationException(); } @Override public V pollFirst() { throw new UnsupportedOperationException(); } @Override public V pollLast() { throw new UnsupportedOperationException(); } @Override public boolean add(V v) { throw new UnsupportedOperationException(); } @Override public boolean remove(Object o) { throw new UnsupportedOperationException(); } @Override public V lower(V v) { throw new UnsupportedOperationException(); } @Override public V floor(V v) { throw new UnsupportedOperationException(); } @Override public V ceiling(V v) { throw new UnsupportedOperationException(); } @Override public V higher(V v) { throw new UnsupportedOperationException(); } @Override public boolean contains(Object o) { throw new UnsupportedOperationException(); } @Override public boolean containsAll(Collection<?> c) { throw new UnsupportedOperationException(); } @Override public NavigableSet<V> descendingSet() { return new BTreeRange<>(this.tree, this.comparator).descendingSet(); } public static class BTreeRange<V> extends BTreeSet<V> implements NavigableSet<V> { protected final V lowerBound, upperBound; protected final boolean inclusiveLowerBound, inclusiveUpperBound; BTreeRange(Object[] tree, Comparator<V> comparator) { this(tree, comparator, null, true, null, true); } BTreeRange(BTreeRange<V> from) { this(from.tree, from.comparator, from.lowerBound, from.inclusiveLowerBound, from.upperBound, from.inclusiveUpperBound); } BTreeRange(Object[] tree, Comparator<V> comparator, V lowerBound, boolean inclusiveLowerBound, V upperBound, boolean inclusiveUpperBound) { super(tree, comparator); this.lowerBound = lowerBound; this.upperBound = upperBound; this.inclusiveLowerBound = inclusiveLowerBound; this.inclusiveUpperBound = inclusiveUpperBound; } // narrowing range constructor - makes this the intersection of the two ranges over the same tree b BTreeRange(BTreeRange<V> a, BTreeRange<V> b) { super(a.tree, a.comparator); assert a.tree == b.tree; final BTreeRange<V> lb, ub; if (a.lowerBound == null) { lb = b; } else if (b.lowerBound == null) { lb = a; } else { int c = comparator.compare(a.lowerBound, b.lowerBound); if (c < 0) lb = b; else if (c > 0) lb = a; else if (!a.inclusiveLowerBound) lb = a; else lb = b; } if (a.upperBound == null) { ub = b; } else if (b.upperBound == null) { ub = a; } else { int c = comparator.compare(b.upperBound, a.upperBound); if (c < 0) ub = b; else if (c > 0) ub = a; else if (!a.inclusiveUpperBound) ub = a; else ub = b; } lowerBound = lb.lowerBound; inclusiveLowerBound = lb.inclusiveLowerBound; upperBound = ub.upperBound; inclusiveUpperBound = ub.inclusiveUpperBound; } @Override protected Cursor<V, V> slice(boolean forwards, boolean permitInversion) { return BTree.slice(tree, comparator, lowerBound, inclusiveLowerBound, upperBound, inclusiveUpperBound, forwards); } @Override public NavigableSet<V> subSet(V fromElement, boolean fromInclusive, V toElement, boolean toInclusive) { return new BTreeRange<>(this, new BTreeRange<>(tree, comparator, fromElement, fromInclusive, toElement, toInclusive)); } @Override public NavigableSet<V> headSet(V toElement, boolean inclusive) { return new BTreeRange<>(this, new BTreeRange<>(tree, comparator, lowerBound, true, toElement, inclusive)); } @Override public NavigableSet<V> tailSet(V fromElement, boolean inclusive) { return new BTreeRange<>(this, new BTreeRange<>(tree, comparator, fromElement, inclusive, null, true)); } @Override public NavigableSet<V> descendingSet() { return new BTreeDescRange<>(this); } } public static class BTreeDescRange<V> extends BTreeRange<V> { BTreeDescRange(BTreeRange<V> from) { super(from.tree, from.comparator, from.lowerBound, from.inclusiveLowerBound, from.upperBound, from.inclusiveUpperBound); } @Override protected Cursor<V, V> slice(boolean forwards, boolean permitInversion) { return super.slice(permitInversion ? !forwards : forwards, false); } @Override public NavigableSet<V> subSet(V fromElement, boolean fromInclusive, V toElement, boolean toInclusive) { return super.subSet(toElement, toInclusive, fromElement, fromInclusive).descendingSet(); } @Override public NavigableSet<V> headSet(V toElement, boolean inclusive) { return super.tailSet(toElement, inclusive).descendingSet(); } @Override public NavigableSet<V> tailSet(V fromElement, boolean inclusive) { return super.headSet(fromElement, inclusive).descendingSet(); } @Override public NavigableSet<V> descendingSet() { return new BTreeRange<>(this); } } }