package com.github.davidmoten.rtree.internal;
import static com.github.davidmoten.guavamini.Optional.of;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import com.github.davidmoten.guavamini.Optional;
import com.github.davidmoten.rtree.Context;
import com.github.davidmoten.rtree.Entry;
import com.github.davidmoten.rtree.Leaf;
import com.github.davidmoten.rtree.Node;
import com.github.davidmoten.rtree.geometry.Geometry;
import com.github.davidmoten.rtree.geometry.ListPair;
import rx.Subscriber;
import rx.functions.Func1;
public final class LeafHelper {
private LeafHelper() {
// prevent instantiation
}
public static <T, S extends Geometry> NodeAndEntries<T, S> delete(
Entry<? extends T, ? extends S> entry, boolean all, Leaf<T, S> leaf) {
List<Entry<T, S>> entries = leaf.entries();
if (!entries.contains(entry)) {
return new NodeAndEntries<T, S>(of(leaf), Collections.<Entry<T, S>> emptyList(), 0);
} else {
final List<Entry<T, S>> entries2 = new ArrayList<Entry<T, S>>(entries);
entries2.remove(entry);
int numDeleted = 1;
// keep deleting if all specified
while (all && entries2.remove(entry))
numDeleted += 1;
if (entries2.size() >= leaf.context().minChildren()) {
Leaf<T, S> node = leaf.context().factory().createLeaf(entries2, leaf.context());
return new NodeAndEntries<T, S>(of(node), Collections.<Entry<T, S>> emptyList(),
numDeleted);
} else {
return new NodeAndEntries<T, S>(Optional.<Node<T, S>> absent(), entries2,
numDeleted);
}
}
}
public static <T, S extends Geometry> List<Node<T, S>> add(
Entry<? extends T, ? extends S> entry, Leaf<T, S> leaf) {
List<Entry<T, S>> entries = leaf.entries();
Context<T, S> context = leaf.context();
@SuppressWarnings("unchecked")
final List<Entry<T, S>> entries2 = Util.add(entries, (Entry<T, S>) entry);
if (entries2.size() <= context.maxChildren())
return Collections
.singletonList((Node<T, S>) context.factory().createLeaf(entries2, context));
else {
ListPair<Entry<T, S>> pair = context.splitter().split(entries2, context.minChildren());
return makeLeaves(pair, context);
}
}
private static <T, S extends Geometry> List<Node<T, S>> makeLeaves(ListPair<Entry<T, S>> pair,
Context<T, S> context) {
List<Node<T, S>> list = new ArrayList<Node<T, S>>(2);
list.add(context.factory().createLeaf(pair.group1().list(), context));
list.add(context.factory().createLeaf(pair.group2().list(), context));
return list;
}
public static <T, S extends Geometry> void search(Func1<? super Geometry, Boolean> condition,
Subscriber<? super Entry<T, S>> subscriber, Leaf<T, S> leaf) {
if (!condition.call(leaf.geometry().mbr())) {
return;
}
for (int i = 0; i < leaf.count(); i++) {
Entry<T, S> entry = leaf.entry(i);
if (subscriber.isUnsubscribed()) {
return;
} else {
if (condition.call(entry.geometry()))
subscriber.onNext(entry);
}
}
}
}