package jane.tool;
import java.util.AbstractMap.SimpleEntry;
import java.util.ArrayList;
import java.util.Map.Entry;
import jane.core.Octets;
import jane.core.OctetsStream;
import jane.core.StorageLevelDB;
public final class LevelDBClear
{
private LevelDBClear()
{
}
public static void main(String[] args) throws Exception
{
if(args.length < 1)
{
System.err.println("USAGE: java jane.tool.LevelDBClear <databasePath.ld> [tableId]");
return;
}
String pathname = args[0].trim();
int tableId = -1;
if(args.length > 1)
{
try
{
tableId = Integer.parseInt(args[1]);
}
catch(NumberFormatException e)
{
}
if(tableId < 0)
{
System.err.println("ERROR: invalid tableId: '" + args[1] + '\'');
return;
}
}
long t = System.currentTimeMillis();
System.err.println("INFO: opening " + pathname + " ...");
long db = StorageLevelDB.leveldb_open(pathname, 0, 0, true);
if(db == 0)
{
System.err.println("ERROR: leveldb_open failed");
return;
}
System.err.println("INFO: clearing " + (tableId >= 0 ? "table:" + tableId : "db") + " ...");
ArrayList<Entry<Octets, Octets>> buf = new ArrayList<>(10000);
long count = 0;
OctetsStream deleted = OctetsStream.wrap(Octets.EMPTY);
OctetsStream keyFrom = (tableId > 0 ? new OctetsStream().marshalUInt(tableId) : deleted);
OctetsStream keyTo;
if(tableId < 0)
keyTo = null;
else if(tableId < Integer.MAX_VALUE)
keyTo = new OctetsStream().marshalUInt(tableId + 1);
else
keyTo = new OctetsStream().marshal1((byte)0xf1);
for(long iter = StorageLevelDB.leveldb_iter_new(db, keyFrom.array(), keyFrom.size(), 2);;)
{
byte[] key = StorageLevelDB.leveldb_iter_next(iter);
if(key == null) break;
OctetsStream keyOs = OctetsStream.wrap(key);
if(keyTo != null && keyOs.compareTo(keyTo) >= 0) break;
buf.add(new SimpleEntry<Octets, Octets>(keyOs, deleted));
if(buf.size() >= 10000)
{
count += buf.size();
StorageLevelDB.leveldb_write(db, buf.iterator());
buf.clear();
}
}
if(!buf.isEmpty())
{
count += buf.size();
StorageLevelDB.leveldb_write(db, buf.iterator());
buf.clear();
}
System.err.println("INFO: closing db ...");
StorageLevelDB.leveldb_close(db);
System.err.println("INFO: done! (count=" + count + ") (" + (System.currentTimeMillis() - t) + " ms)");
}
}