/**
* Copyright (C) 2009-2015 FoundationDB, LLC
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.foundationdb.server.spatial;
import com.geophile.z.Cursor;
import com.geophile.z.DuplicateRecordException;
import com.geophile.z.Index;
import java.util.Iterator;
import java.util.TreeSet;
import java.util.concurrent.atomic.AtomicInteger;
/**
* TreeIndex implements the {@link com.geophile.z.Index} interface in terms of a {@link java.util.TreeMap}.
* A TreeIndex is not safe for use for simultaneous use by multiple threads.
*/
public class TreeIndex extends Index<TestRecord>
{
// Object interface
@Override
public String toString()
{
return name;
}
// Index interface
@Override
public void add(TestRecord TestRecord)
{
TestRecord copy = newRecord();
TestRecord.copyTo(copy);
boolean added = tree.add(copy);
if (!added) {
throw new DuplicateRecordException(copy);
}
}
@Override
public boolean remove(long z, TestRecord.Filter<TestRecord> filter)
{
boolean foundTestRecord = false;
boolean zMatch = true;
Iterator<TestRecord> iterator = tree.tailSet(key(z)).iterator();
while (zMatch && iterator.hasNext() && !foundTestRecord) {
TestRecord TestRecord = iterator.next();
if (TestRecord.z() == z) {
foundTestRecord = filter.select(TestRecord);
} else {
zMatch = false;
}
}
if (foundTestRecord) {
iterator.remove();
}
return foundTestRecord;
}
@Override
public Cursor<TestRecord> cursor()
{
return new TreeIndexCursor(this);
}
@Override
public TestRecord newRecord()
{
return new TestRecord();
}
@Override
public boolean blindUpdates()
{
return false;
}
@Override
public boolean stableRecords()
{
return false;
}
// TreeIndex
public TreeIndex()
{
this.tree = new TreeSet<>(TestRecord.COMPARATOR);
}
// For use by this package
TreeSet<TestRecord> tree()
{
return tree;
}
// For use by this class
private TestRecord key(long z)
{
TestRecord keyTestRecord = newRecord();
keyTestRecord.z(z);
return keyTestRecord;
}
// Class state
private static final AtomicInteger idGenerator = new AtomicInteger(0);
// Object state
private final String name = String.format("TreeIndex(%s)", idGenerator.getAndIncrement());
private final TreeSet<TestRecord> tree;
}