|
|
|
@ -36,6 +36,7 @@ import java.util.List;
|
|
|
|
|
import java.util.Map;
|
|
|
|
|
import java.util.TreeMap;
|
|
|
|
|
import java.util.TreeSet;
|
|
|
|
|
import java.util.concurrent.ConcurrentSkipListMap;
|
|
|
|
|
|
|
|
|
|
import net.yacy.cora.document.encoding.ASCII;
|
|
|
|
|
import net.yacy.cora.order.CloneableIterator;
|
|
|
|
@ -73,7 +74,7 @@ public class Table implements Index, Iterable<Row.Entry> {
|
|
|
|
|
private final static ConcurrentLog log = new ConcurrentLog("TABLE");
|
|
|
|
|
|
|
|
|
|
/** Map all active table instances by file name */
|
|
|
|
|
private final static TreeMap<String, Table> tableTracker = new TreeMap<String, Table>();
|
|
|
|
|
private final static Map<String, Table> tableTracker = new ConcurrentSkipListMap<String, Table>();
|
|
|
|
|
private final static long maxarraylength = 134217727L; // (2^27-1) that may be the maximum size of array length in some JVMs
|
|
|
|
|
|
|
|
|
|
private final long minmemremaining; // if less than this memory is remaininig, the memory copy of a table is abandoned
|
|
|
|
@ -270,14 +271,14 @@ public class Table implements Index, Iterable<Row.Entry> {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// track this table
|
|
|
|
|
synchronized (tableTracker) {tableTracker.put(tablefile.toString(), this);}
|
|
|
|
|
tableTracker.put(tablefile.toString(), this);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public synchronized void warmUp() {
|
|
|
|
|
warmUp0();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void warmUp0() {
|
|
|
|
|
private final void warmUp0() {
|
|
|
|
|
// remove doubles
|
|
|
|
|
try {
|
|
|
|
|
final ArrayList<long[]> doubles = this.index.removeDoubles();
|
|
|
|
@ -451,7 +452,7 @@ public class Table implements Index, Iterable<Row.Entry> {
|
|
|
|
|
stats.keyChunkSize = (((RowHandleMap) this.index).row().objectsize);
|
|
|
|
|
stats.keyMem = (long)((RowHandleMap) this.index).row().objectsize * (long)this.index.size();
|
|
|
|
|
}
|
|
|
|
|
if(table != null) {
|
|
|
|
|
if(this.table != null) {
|
|
|
|
|
stats.valueChunkSize = this.table.row().objectsize;
|
|
|
|
|
stats.valueMem = (long)this.table.row().objectsize * (long)this.table.size();
|
|
|
|
|
}
|
|
|
|
@ -616,7 +617,7 @@ public class Table implements Index, Iterable<Row.Entry> {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private Entry get0(final byte[] key) throws IOException {
|
|
|
|
|
private final Entry get0(final byte[] key) throws IOException {
|
|
|
|
|
if (this.file == null || this.index == null) return null;
|
|
|
|
|
final int i = (int) this.index.get(key);
|
|
|
|
|
if (i == -1) return null;
|
|
|
|
@ -643,7 +644,7 @@ public class Table implements Index, Iterable<Row.Entry> {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public Map<byte[], Row.Entry> get(final Collection<byte[]> keys, final boolean forcecopy) throws IOException, InterruptedException {
|
|
|
|
|
public final Map<byte[], Row.Entry> get(final Collection<byte[]> keys, final boolean forcecopy) throws IOException, InterruptedException {
|
|
|
|
|
final Map<byte[], Row.Entry> map = new TreeMap<byte[], Row.Entry>(row().objectOrder);
|
|
|
|
|
Row.Entry entry;
|
|
|
|
|
for (final byte[] key: keys) {
|
|
|
|
@ -654,13 +655,13 @@ public class Table implements Index, Iterable<Row.Entry> {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public boolean has(final byte[] key) {
|
|
|
|
|
public final boolean has(final byte[] key) {
|
|
|
|
|
if (this.index == null) return false;
|
|
|
|
|
return this.index.has(key);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public synchronized CloneableIterator<byte[]> keys(final boolean up, final byte[] firstKey) throws IOException {
|
|
|
|
|
public final synchronized CloneableIterator<byte[]> keys(final boolean up, final byte[] firstKey) throws IOException {
|
|
|
|
|
return this.index.keys(up, firstKey);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -723,7 +724,7 @@ public class Table implements Index, Iterable<Row.Entry> {
|
|
|
|
|
* @throws SpaceExceededException
|
|
|
|
|
*/
|
|
|
|
|
@Override
|
|
|
|
|
public boolean put(final Entry row) throws IOException, SpaceExceededException {
|
|
|
|
|
public final boolean put(final Entry row) throws IOException, SpaceExceededException {
|
|
|
|
|
assert row != null;
|
|
|
|
|
if (this.file == null || row == null) return true;
|
|
|
|
|
final byte[] rowb = row.bytes();
|
|
|
|
@ -769,7 +770,7 @@ public class Table implements Index, Iterable<Row.Entry> {
|
|
|
|
|
* @throws IOException
|
|
|
|
|
* @throws SpaceExceededException
|
|
|
|
|
*/
|
|
|
|
|
private void removeInFile(final int i) throws IOException, SpaceExceededException {
|
|
|
|
|
private final void removeInFile(final int i) throws IOException, SpaceExceededException {
|
|
|
|
|
assert i >= 0;
|
|
|
|
|
|
|
|
|
|
final byte[] p = new byte[this.rowdef.objectsize];
|
|
|
|
@ -828,12 +829,12 @@ public class Table implements Index, Iterable<Row.Entry> {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public boolean delete(final byte[] key) throws IOException {
|
|
|
|
|
public final boolean delete(final byte[] key) throws IOException {
|
|
|
|
|
return remove(key) != null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public synchronized Entry remove(final byte[] key) throws IOException {
|
|
|
|
|
public final synchronized Entry remove(final byte[] key) throws IOException {
|
|
|
|
|
assert this.file.size() == this.index.size() : "file.size() = " + this.file.size() + ", index.size() = " + this.index.size();
|
|
|
|
|
assert this.table == null || this.table.size() == this.index.size() : "table.size() = " + this.table.size() + ", index.size() = " + this.index.size();
|
|
|
|
|
assert key.length == this.rowdef.primaryKeyLength;
|
|
|
|
@ -928,7 +929,7 @@ public class Table implements Index, Iterable<Row.Entry> {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public synchronized Entry removeOne() throws IOException {
|
|
|
|
|
public final synchronized Entry removeOne() throws IOException {
|
|
|
|
|
//assert this.file.size() == this.index.size() : "file.size() = " + this.file.size() + ", index.size() = " + this.index.size();
|
|
|
|
|
assert this.table == null || this.table.size() == this.index.size() : "table.size() = " + this.table.size() + ", index.size() = " + this.index.size();
|
|
|
|
|
final byte[] le = new byte[this.rowdef.objectsize];
|
|
|
|
@ -955,7 +956,7 @@ public class Table implements Index, Iterable<Row.Entry> {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public List<Row.Entry> top(int count) throws IOException {
|
|
|
|
|
public final List<Row.Entry> top(int count) throws IOException {
|
|
|
|
|
if (count > this.size()) count = this.size();
|
|
|
|
|
final ArrayList<Row.Entry> list = new ArrayList<Row.Entry>();
|
|
|
|
|
if (this.file == null || this.index == null || this.size() == 0 || count == 0) return list;
|
|
|
|
@ -971,7 +972,7 @@ public class Table implements Index, Iterable<Row.Entry> {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public List<Row.Entry> random(int count) throws IOException {
|
|
|
|
|
public final List<Row.Entry> random(int count) throws IOException {
|
|
|
|
|
if (count > this.size()) count = this.size();
|
|
|
|
|
final ArrayList<Row.Entry> list = new ArrayList<Row.Entry>();
|
|
|
|
|
if (this.file == null || this.index == null || this.size() == 0 || count == 0) return list;
|
|
|
|
@ -996,23 +997,23 @@ public class Table implements Index, Iterable<Row.Entry> {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public Row row() {
|
|
|
|
|
public final Row row() {
|
|
|
|
|
return this.rowdef;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public int size() {
|
|
|
|
|
public final int size() {
|
|
|
|
|
if (this.index == null) return 0;
|
|
|
|
|
return this.index.size();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public boolean isEmpty() {
|
|
|
|
|
public final boolean isEmpty() {
|
|
|
|
|
return this.index == null || this.index.isEmpty();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public Iterator<Entry> iterator() {
|
|
|
|
|
public final Iterator<Entry> iterator() {
|
|
|
|
|
try {
|
|
|
|
|
return rows();
|
|
|
|
|
} catch (final IOException e) {
|
|
|
|
@ -1026,7 +1027,7 @@ public class Table implements Index, Iterable<Row.Entry> {
|
|
|
|
|
return new rowIteratorNoOrder();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private class rowIteratorNoOrder implements CloneableIterator<Entry> {
|
|
|
|
|
private final class rowIteratorNoOrder implements CloneableIterator<Entry> {
|
|
|
|
|
Iterator<Map.Entry<byte[], Long>> i;
|
|
|
|
|
long idx;
|
|
|
|
|
byte[] key;
|
|
|
|
@ -1038,17 +1039,17 @@ public class Table implements Index, Iterable<Row.Entry> {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public CloneableIterator<Entry> clone(final Object modifier) {
|
|
|
|
|
public final CloneableIterator<Entry> clone(final Object modifier) {
|
|
|
|
|
return new rowIteratorNoOrder();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public boolean hasNext() {
|
|
|
|
|
public final boolean hasNext() {
|
|
|
|
|
return this.i != null && this.i.hasNext();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public Entry next() {
|
|
|
|
|
public final Entry next() {
|
|
|
|
|
final Map.Entry<byte[], Long> entry = this.i.next();
|
|
|
|
|
if (entry == null) return null;
|
|
|
|
|
this.key = entry.getKey();
|
|
|
|
@ -1062,7 +1063,7 @@ public class Table implements Index, Iterable<Row.Entry> {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public void remove() {
|
|
|
|
|
public final void remove() {
|
|
|
|
|
if (this.key != null) {
|
|
|
|
|
try {
|
|
|
|
|
removeInFile((int) this.idx);
|
|
|
|
@ -1074,7 +1075,7 @@ public class Table implements Index, Iterable<Row.Entry> {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public void close() {
|
|
|
|
|
public final void close() {
|
|
|
|
|
if (this.i instanceof CloneableIterator) {
|
|
|
|
|
((CloneableIterator<Map.Entry<byte[], Long>>) this.i).close();
|
|
|
|
|
}
|
|
|
|
@ -1087,7 +1088,7 @@ public class Table implements Index, Iterable<Row.Entry> {
|
|
|
|
|
return new rowIterator(up, firstKey);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private class rowIterator implements CloneableIterator<Entry> {
|
|
|
|
|
private final class rowIterator implements CloneableIterator<Entry> {
|
|
|
|
|
private final CloneableIterator<byte[]> i;
|
|
|
|
|
private final boolean up;
|
|
|
|
|
private final byte[] fk;
|
|
|
|
|