package org.basex.data;
import static org.junit.Assert.*;
import java.util.*;
import org.basex.index.*;
import org.basex.util.*;
import org.junit.*;
/**
* Base class with common functionality for all ID -> PRE mapping tests.
* @author BaseX Team 2005-17, BSD License
* @author Dimitar Popov
*/
public abstract class IdPreMapBulkTestBase {
/** Number of update operations to execute in each test. */
int opcount = 7000;
/** Initial number of records. */
int baseid = 400;
/** ID -> PRE map to compare to. */
private DummyIdPreMap basemap;
/** ID -> PRE map to test. */
private IdPreMap testedmap;
/** Sequence of performed operations and parameters. */
private ArrayList<int[]> ops;
/** Set-up method. */
@Before
public void setUp() {
final int ml = baseid + 1;
final int[] map = new int[ml];
for(int m = 0; m < ml; m++) map[m] = m;
basemap = new DummyIdPreMap(map);
testedmap = new IdPreMap(baseid);
ops = new ArrayList<>(baseid + opcount);
}
/**
* Insert a <pre, id> pair in {@link #basemap} and {@link #testedmap}.
* @param pre pre value
* @param id id value
* @param c number of inserted records
*/
final void insert(final int pre, final int id, final int c) {
ops.add(new int[] { pre, id, c});
testedmap.insert(pre, id, c);
basemap.insert(pre, id, c);
}
/**
* Delete a <pre, id> pair from {@link #basemap} and {@link #testedmap}.
* @param pre pre value
* @param c number of deleted records (negative)
*/
final void delete(final int pre, final int c) {
ops.add(new int[] { pre, basemap.id(pre), c});
testedmap.delete(pre, basemap.id(pre), c);
basemap.delete(pre, basemap.id(pre), c);
}
/** Check the two mappings. */
final void check() {
final int bs = basemap.size();
for(int pre = 0; pre < bs; pre++) {
final int id = basemap.id(pre);
final int p = testedmap.pre(id);
if(pre != p) {
dump();
fail("Wrong PRE for ID=" + id + ": expected " + pre + ", actual " + p);
}
}
}
/** Print inserted and deleted records and the tested map. */
final void dump() {
final StringBuilder s = new StringBuilder();
for(final int[] o : ops) {
s.append(o[2] > 0 ? "insert(" : "delete(");
s.append(o[0]);
s.append(',');
s.append(o[1]);
s.append(',');
s.append(o[2]);
s.append(");\n");
}
Util.errln("Operations:\n" + s);
Util.errln(testedmap);
}
/**
* Dummy implementation of ID -> PRE map: very slow, but simple and correct.
* @author BaseX Team 2005-17, BSD License
* @author Dimitar Popov
*/
protected static class DummyIdPreMap extends IdPreMap {
/** ID list. */
private final ArrayList<Integer> idlist;
/**
* Constructor.
* @param list initial list of ids.
*/
public DummyIdPreMap(final int[] list) {
super(list.length - 1);
idlist = new ArrayList<>(list.length);
for(final int l : list) idlist.add(l);
}
@Override
public void insert(final int pre, final int id, final int c) {
for(int i = 0; i < c; ++i) idlist.add(pre + i, id + i);
}
@Override
public void delete(final int pre, final int id, final int c) {
for(int i = 0; i < -c; ++i) idlist.remove(pre);
}
@Override
public int pre(final int id) {
return idlist.indexOf(id);
}
@Override
public int size() {
return idlist.size();
}
/**
* ID of the record with a given PRE.
* @param pre record PRE
* @return record ID
*/
public int id(final int pre) {
return idlist.get(pre);
}
@Override
public String toString() {
final StringBuilder spres = new StringBuilder(), sids = new StringBuilder();
final int is = idlist.size();
for(int i = 0; i < is; ++i) {
spres.append(i).append(' ');
sids.append(idlist.get(i)).append(' ');
}
return spres.append('\n').append(sids).toString();
}
}
}