package de.uni_luebeck.inb.krabbenhoeft.eQTL.server.helpers.persistence; import java.nio.ByteBuffer; import java.util.Arrays; import java.util.HashMap; import java.util.Map; import java.util.Random; import org.apache.cassandra.service.Column; import org.apache.cassandra.service.SuperColumn; import de.uni_luebeck.inb.krabbenhoeft.eQTL.entities.Category; import de.uni_luebeck.inb.krabbenhoeft.eQTL.entities.ColumnForDataSetLayer; import de.uni_luebeck.inb.krabbenhoeft.eQTL.entities.HajoEntity; import de.uni_luebeck.inb.krabbenhoeft.eQTL.entities.InvalidColumnException; import de.uni_luebeck.inb.krabbenhoeft.eQTL.entities.InvalidTypeException; import de.uni_luebeck.inb.krabbenhoeft.eQTL.entities.ColumnForDataSetLayer.ColumType; public class CassandraEntityContainer { public static int getRandomBlock() { return new Random().nextInt(HajoEntity.NUMBER_OF_PARALLEL_BLOCK_IDS); } protected CassandraSession cassandra; protected Map<String, ColumnForDataSetLayer> columnName2columnDescriptionRead = new HashMap<String, ColumnForDataSetLayer>(); protected Map<String, ColumnForDataSetLayer> columnName2columnDescriptionWrite = new HashMap<String, ColumnForDataSetLayer>(); CassandraEntityContainer(CassandraSession cassandra) { this.cassandra = cassandra; } protected static byte[] t2b(final String text) { return text.getBytes(CassandraSession.charset); } protected static String b2t(byte[] data) { return new String(data, CassandraSession.charset); } public CassandraEntityContainer() { super(); } protected ColumnForDataSetLayer ensureColumnExistsAndHasType(Map<String, ColumnForDataSetLayer> name2column, String propertyName, ColumType columType) { if (!name2column.containsKey(propertyName)) throw new InvalidColumnException(propertyName); final ColumnForDataSetLayer column = name2column.get(propertyName); if (column.getType() != columType) throw new InvalidTypeException(propertyName, columType); return column; } public class CassandraHajoEntity implements HajoEntity { SuperColumn superColumn; CassandraHajoEntity(SuperColumn superColumn) { this.superColumn = superColumn; } byte[] getColumn(byte[] name) { for (Column col : superColumn.columns) { if (Arrays.equals(col.name, name)) return col.value; } return null; } private void setColumn(byte[] name, byte[] value) { for (Column col : superColumn.columns) { if (col.name.equals(name)) { col.setValue(value); col.setTimestamp(CassandraSession.ts()); return; } } superColumn.columns.add(new Column(name, value, CassandraSession.ts())); } public byte[] getEntityKey() { return superColumn.name; } public Category getCategory(String propertyName) { final byte[] name = t2b(propertyName); ensureColumnExistsAndHasType(columnName2columnDescriptionRead, propertyName, ColumType.Category); return Category.wrap(b2t(getColumn(name))); } public String getName(String propertyName) { final byte[] name = t2b(propertyName); ensureColumnExistsAndHasType(columnName2columnDescriptionRead, propertyName, ColumType.Name); return b2t(getColumn(name)); } public double getNumerical(String propertyName) { final byte[] name = t2b(propertyName); ensureColumnExistsAndHasType(columnName2columnDescriptionRead, propertyName, ColumType.Numerical); return ByteBuffer.wrap(getColumn(name)).getDouble(); } public long getLocation(String propertyName) { final byte[] name = t2b(propertyName); ensureColumnExistsAndHasType(columnName2columnDescriptionRead, propertyName, ColumType.Location); return ByteBuffer.wrap(getColumn(name)).getLong(); } public void setCategory(String propertyName, Category value) { final byte[] name = t2b(propertyName); final ColumnForDataSetLayer column = ensureColumnExistsAndHasType(columnName2columnDescriptionWrite, propertyName, ColumType.Category); final byte[] bytes = t2b(value.getCategory()); setColumn(name, bytes); column.getValues().add(value.getCategory()); } public void setName(String propertyName, String value) { final byte[] name = t2b(propertyName); ensureColumnExistsAndHasType(columnName2columnDescriptionWrite, propertyName, ColumType.Name); final byte[] bytes = t2b(value); setColumn(name, bytes); } public void setNumerical(String propertyName, double value) { final byte[] name = t2b(propertyName); final ColumnForDataSetLayer column = ensureColumnExistsAndHasType(columnName2columnDescriptionWrite, propertyName, ColumType.Numerical); final byte[] bytes = ByteBuffer.allocate(8).putDouble(value).array(); setColumn(name, bytes); if (value > column.getMax()) column.setMax(value); if (value < column.getMin()) column.setMin(value); } public void setLocation(String propertyName, long value) { final byte[] name = t2b(propertyName); final ColumnForDataSetLayer column = ensureColumnExistsAndHasType(columnName2columnDescriptionWrite, propertyName, ColumType.Location); final byte[] bytes = ByteBuffer.allocate(8).putLong(value).array(); setColumn(name, bytes); if (value > column.getLmax()) column.setLmax(value); if (value < column.getLmin()) column.setLmin(value); } public String getAsString(String name) { switch (columnName2columnDescriptionRead.get(name).getType()) { case Category: return getCategory(name).getCategory(); case Name: return getName(name); case Numerical: return Double.toString(getNumerical(name)); case Location: return Long.toString(getLocation(name)); } return null; } byte[] calculateIndexFor(final byte[] bytes) { return ByteBuffer.allocate(bytes.length + 4).put(bytes).put(superColumn.name).array(); } } }