package org.yamcs.parameterarchive;
import java.io.PrintStream;
import java.nio.ByteBuffer;
import java.util.HashMap;
import java.util.Map;
import org.rocksdb.ColumnFamilyHandle;
import org.rocksdb.RocksDB;
import org.rocksdb.RocksDBException;
import org.rocksdb.RocksIterator;
import org.yamcs.utils.IntArray;
import org.yamcs.utils.SortedIntArray;
/**
* Stores a map between
* List<parameter_id> and ParameterGroup_id.
*
* Stores data one column family:
* pgid2pg
* key = ParameterGroup_id
* value = SortedVarArray of parameter_id
*
*
* Backed by RocksDB
* @author nm
*
*/
public class ParameterGroupIdDb {
final RocksDB db;
final ColumnFamilyHandle pgid2pg_cfh;
int highestPgId=0;
Map<SortedIntArray, Integer> pg2pgidCache = new HashMap<>();
ParameterGroupIdDb(RocksDB db, ColumnFamilyHandle pgid2pg_cfh) {
this.db = db;
this.pgid2pg_cfh = pgid2pg_cfh;
readDb();
}
/**
* Creates (if not already there) a new ParameterGroupId for the given parameter id array
*
* @param s
* @return the parameterGroupId for the given parameter id array
* @throws RocksDBException
*/
public synchronized int createAndGet(SortedIntArray s) throws RocksDBException {
Integer pgid = pg2pgidCache.get(s);
if(pgid == null) {
int x = ++highestPgId;
pgid = x;
db.put(pgid2pg_cfh, encodeInt(x), s.encodeToVarIntArray());
pg2pgidCache.put(s, pgid);
}
return pgid;
}
/**
* Creates (if not already there) a new ParameterGroupId for the given parameter id array
*
* The parameter id array is sorted before
* @param parameterIdArray
* @return he parameterGroupId for the given parameter id array
* @throws RocksDBException
*/
public int createAndGet(int[] parameterIdArray) throws RocksDBException {
return createAndGet(new SortedIntArray(parameterIdArray));
}
private byte[] encodeInt(int x) {
return ByteBuffer.allocate(4).putInt(x).array();
}
private void readDb() {
try(RocksIterator it = db.newIterator(pgid2pg_cfh)) {
it.seekToFirst();
while(it.isValid()) {
int pgid = ByteBuffer.wrap(it.key()).getInt();
if(highestPgId < pgid) {
highestPgId = pgid;
}
SortedIntArray svil = SortedIntArray.decodeFromVarIntArray(it.value());
pg2pgidCache.put(svil, pgid);
it.next();
}
}
}
public SortedIntArray getParameterGroup(int pg) {
for (Map.Entry<SortedIntArray, Integer> e: pg2pgidCache.entrySet()) {
if(e.getValue()==pg) {
return e.getKey();
}
}
throw new IllegalArgumentException("No parameter group with the id "+pg);
}
@Override
public String toString() {
return pg2pgidCache.toString();
}
public void print(PrintStream out) {
for(Map.Entry<SortedIntArray, Integer> e: pg2pgidCache.entrySet()) {
out.println(e.getValue()+": "+e.getKey());
}
}
/**
* get all parameter group ids for the parameters from which this parameter id is part of
* @param pid
* @return the parameter group ids for the parameters groups that contain the pid
*/
public synchronized int[] getAllGroups(int pid) {
IntArray r = new IntArray();
for (Map.Entry<SortedIntArray, Integer> e: pg2pgidCache.entrySet()) {
SortedIntArray s = e.getKey();
if(s.contains(pid)) {
r.add(e.getValue());
}
}
return r.toArray();
}
}