public String getStringFor(T nameRecord) { int recordToFind = nameRecord.getNameId(); Iterator<DynamicRecord> records = nameRecord.getNameRecords().iterator(); Collection<DynamicRecord> relevantRecords = new ArrayList<DynamicRecord>(); while (recordToFind != Record.NO_NEXT_BLOCK.intValue() && records.hasNext()) { DynamicRecord record = records.next(); if (record.inUse() && record.getId() == recordToFind) { recordToFind = (int) record.getNextBlock(); // // TODO: optimize here, high chance next is right one relevantRecords.add(record); records = nameRecord.getNameRecords().iterator(); } } return (String) PropertyStore.getStringFor( PropertyStore.readFullByteArray(nameRecord.getNameId(), relevantRecords, nameStore)); }
public static Pair<byte[] /*header in the first record*/, byte[] /*all other bytes*/> readFullByteArray( long startRecord, Iterable<DynamicRecord> records, AbstractDynamicStore store, PropertyType propertyType) { long recordToFind = startRecord; Map<Long, DynamicRecord> recordsMap = new HashMap<Long, DynamicRecord>(); for (DynamicRecord record : records) { recordsMap.put(record.getId(), record); } byte[] header = null; List<byte[]> byteList = new LinkedList<byte[]>(); int totalSize = 0; while (recordToFind != Record.NO_NEXT_BLOCK.intValue()) { DynamicRecord record = recordsMap.get(recordToFind); if (record.isLight()) { store.makeHeavy(record); } int offset = 0; if (recordToFind == startRecord) { // This is the first one, read out the header separately header = propertyType.readDynamicRecordHeader(record.getData()); offset = header.length; } byteList.add(record.getData()); totalSize += (record.getData().length - offset); recordToFind = record.getNextBlock(); } byte[] bArray = new byte[totalSize]; int sourceOffset = header.length; int offset = 0; for (byte[] currentArray : byteList) { System.arraycopy( currentArray, sourceOffset, bArray, offset, currentArray.length - sourceOffset); offset += (currentArray.length - sourceOffset); sourceOffset = 0; } return Pair.of(header, bArray); }
public class DynamicRecord extends AbstractRecord { private byte[] data = null; private char[] charData = null; private int length; private int prevBlock = Record.NO_PREV_BLOCK.intValue(); private int nextBlock = Record.NO_NEXT_BLOCK.intValue(); private boolean isLight = false; private int type; public DynamicRecord(int id) { super(id); } public int getType() { return type; } void setType(int type) { this.type = type; } void setIsLight(boolean status) { this.isLight = status; } public boolean isLight() { return isLight; } public void setLength(int length) { this.length = length; } public void setInUse(boolean inUse) { super.setInUse(inUse); if (!inUse) { data = null; } } public void setInUse(boolean inUse, int type) { this.type = type; this.setInUse(inUse); } public void setData(byte[] data) { isLight = false; this.length = data.length; this.data = data; } public void setCharData(char[] data) { isLight = false; this.length = data.length * 2; this.charData = data; } public int getLength() { return length; } public byte[] getData() { assert !isLight; assert charData == null; return data; } public boolean isCharData() { return charData != null; } public char[] getDataAsChar() { assert !isLight; assert data == null; return charData; } public int getPrevBlock() { return prevBlock; } public void setPrevBlock(int prevBlock) { this.prevBlock = prevBlock; } public int getNextBlock() { return nextBlock; } public void setNextBlock(int nextBlock) { this.nextBlock = nextBlock; } @Override public String toString() { StringBuffer buf = new StringBuffer(); buf.append("DynamicRecord[").append(getId()).append(",").append(inUse()); if (inUse()) { buf.append(",") .append(prevBlock) .append(",") .append(isLight ? null : data.length) .append(",") .append(nextBlock) .append("]"); } return buf.toString(); } }