package org.yamcs.yarch.rocksdb; import static org.junit.Assert.*; import java.util.Iterator; import java.util.List; import org.junit.After; import org.junit.Before; import org.junit.Test; import org.rocksdb.ColumnFamilyHandle; import org.yamcs.TimeInterval; import org.yamcs.utils.TimeEncoding; import org.yamcs.yarch.HistogramRecord; import org.yamcs.yarch.Partition; import org.yamcs.yarch.TableDefinition; import org.yamcs.yarch.TableWriter; import org.yamcs.yarch.Tuple; import org.yamcs.yarch.YarchTestCase; import org.yamcs.yarch.TableWriter.InsertMode; public class HistogramRebuilderTest extends YarchTestCase { String tblName = "HistogramRebuilderTest"; TableDefinition tblDef; RdbStorageEngine rse; long t1 = TimeEncoding.parse("2016-12-16T00:00:00"); @Before public void populate() throws Exception { String query="create table "+tblName+"(gentime timestamp, seqNum int, name string, primary key(gentime, seqNum)) histogram(name) partition by time(gentime) table_format=compressed"; ydb.execute(query); tblDef= ydb.getTable(tblName); rse = (RdbStorageEngine) ydb.getStorageEngine(tblDef); TableWriter tw = rse.newTableWriter(tblDef, InsertMode.INSERT); tw.onTuple(null, new Tuple(tblDef.getTupleDefinition(), new Object[]{1000L, 10, "p1"})); tw.onTuple(null, new Tuple(tblDef.getTupleDefinition(), new Object[]{2000L, 20, "p1"})); tw.onTuple(null, new Tuple(tblDef.getTupleDefinition(), new Object[]{3000L, 30, "p2"})); tw.onTuple(null, new Tuple(tblDef.getTupleDefinition(), new Object[]{t1, 30, "p2"})); tw.close(); } @After public void dropTable() throws Exception { ydb.execute("drop table "+tblName); } @Test public void testDeleteValues() throws Exception { TimeInterval interval = new TimeInterval(); Iterator<HistogramRecord> iter = rse.getHistogramIterator(tblDef, "name", interval, 0); assertNumElementsEqual(iter, 3); HistogramRebuilder rebuilder = new HistogramRebuilder(ydb, tblName); rebuilder.deleteHistograms(new TimeInterval(1000L, 1000L)); iter = rse.getHistogramIterator(tblDef, "name", interval, 0); assertNumElementsEqual(iter, 1); assertNotNull(getHistoCf(1000L, "name")); rebuilder.rebuild(new TimeInterval(0, 2000)).get(); iter = rse.getHistogramIterator(tblDef, "name", interval, 0); assertNumElementsEqual(iter, 3); } @Test public void testDeleteCfh() throws Exception { TimeInterval interval = new TimeInterval(); Iterator<HistogramRecord> iter = rse.getHistogramIterator(tblDef, "name", interval, 0); assertNumElementsEqual(iter, 3); HistogramRebuilder rebuilder = new HistogramRebuilder(ydb, tblName); rebuilder.deleteHistograms(TimeInterval.openStart(1000L)); iter = rse.getHistogramIterator(tblDef, "name", interval, 0); assertNumElementsEqual(iter, 1); assertNull(getHistoCf(1000L, "name")); assertNull(getHistoCf(t1, "name")); rebuilder.rebuild(TimeInterval.openStart(t1)).get(); iter = rse.getHistogramIterator(tblDef, "name", interval, 0); assertNumElementsEqual(iter, 3); } @Test public void testRebuildAll() throws Exception { TimeInterval interval = new TimeInterval(); Iterator<HistogramRecord> iter = rse.getHistogramIterator(tblDef, "name", interval, 0); assertNumElementsEqual(iter, 3); HistogramRebuilder rebuilder = new HistogramRebuilder(ydb, tblName); rebuilder.deleteHistograms(new TimeInterval()); iter = rse.getHistogramIterator(tblDef, "name", interval, 0); assertNumElementsEqual(iter, 0); assertNull(getHistoCf(1000L, "name")); assertNull(getHistoCf(t1, "name")); rebuilder.rebuild(new TimeInterval()).get(); iter = rse.getHistogramIterator(tblDef, "name", interval, 0); assertNumElementsEqual(iter, 3); } private void assertNumElementsEqual(Iterator<HistogramRecord> iter, int k) { int num =0; while(iter.hasNext()) { num++; iter.next(); } assertEquals(k, num); } private ColumnFamilyHandle getHistoCf(long start, String colName) throws Exception { String cfHistoName = AbstractTableWriter.getHistogramColumnFamilyName(colName); RdbPartition p0 = getFirstPartition(1000L); YRDB rdb = RDBFactory.getInstance(ydb.getName()).getRdb(tblDef.getDataDir()+"/"+p0.dir, false); return rdb.getColumnFamilyHandle(cfHistoName); } private RdbPartition getFirstPartition(long start) { Iterator<List<Partition>> it = rse.getPartitionManager(tblDef).iterator(start, null); if(!it.hasNext()) return null; return (RdbPartition) it.next().get(0); } }