blob: d80b32eaa00d7bca2d0df8277a7ed35fe50b360d [file] [log] [blame]
/*
* 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);
}
}
}