package org.wonderdb.core.collection; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; import org.wonderdb.serialize.ColumnSerializer; import org.wonderdb.serialize.record.RecordSerializer; import org.wonderdb.types.BlockPtr; import org.wonderdb.types.ColumnSerializerMetadata; import org.wonderdb.types.DBType; import org.wonderdb.types.Extended; import org.wonderdb.types.ExtendedColumn; import org.wonderdb.types.TableRecordMetadata; import org.wonderdb.types.TypeMetadata; import org.wonderdb.types.record.ExtendedTableRecord; import org.wonderdb.types.record.IndexRecord; import org.wonderdb.types.record.ListRecord; import org.wonderdb.types.record.ObjectListRecord; import org.wonderdb.types.record.ObjectRecord; import org.wonderdb.types.record.Record; import org.wonderdb.types.record.TableRecord; public class RecordUtils { private static RecordUtils instance = new RecordUtils(); private RecordUtils() { } public static RecordUtils getInstance() { return instance; } public TableRecord convertToExtended(TableRecord newRecord, Set<Object> pinnedBlocks, TypeMetadata meta, int maxBlockSize, int blockUsedSize, byte fileId) { int recordSize = RecordSerializer.getInstance().getRecordSize(newRecord, meta); if ((maxBlockSize - blockUsedSize - recordSize) > 0) { return newRecord; } Map<Integer, DBType> map = newRecord.getColumnMap(); Iterator<Integer> iter = map.keySet().iterator(); boolean recordSizeChanging = false; while (iter.hasNext()) { int columnId = iter.next(); int type = ((TableRecordMetadata) meta).getColumnIdTypeMap().get(columnId); DBType newColumn = newRecord.getColumnMap().get(columnId); int size = ColumnSerializer.getInstance().getObjectRealSize(newColumn, new ColumnSerializerMetadata(type)); if (size > maxBlockSize) { List<BlockPtr> list = ExtendedUtils.getInstance().extend(fileId, pinnedBlocks); ExtendedColumn ec = new ExtendedColumn(newColumn, list); map.put(columnId, ec); recordSizeChanging = true; } } if (recordSizeChanging) { recordSize = RecordSerializer.getInstance().getRecordSize(newRecord, meta); } if ((maxBlockSize - blockUsedSize - recordSize) > 0) { return newRecord; } else { List<BlockPtr> list = ExtendedUtils.getInstance().extend(fileId, pinnedBlocks); ExtendedTableRecord etr = new ExtendedTableRecord(map, list); return etr; } } public TableRecord convertToExtended(TableRecord oldRecord, TableRecord newRecord, Set<Object> pinnedBlocks, TypeMetadata meta, int blockUsedSize, int maxBlockSize, byte fileId) { TableRecord retRecord = oldRecord; Map<Integer, DBType> map = oldRecord.getColumnMap(); TableRecordMetadata trsm = (TableRecordMetadata) meta; Iterator<Integer> iter = map.keySet().iterator(); int oldRecordSize = RecordSerializer.getInstance().getRecordSize(oldRecord, meta); while (iter.hasNext()) { int columnId = iter.next(); DBType oldColumn = map.get(columnId); if (newRecord.getColumnMap().containsKey(columnId)) { int type = trsm.getColumnIdTypeMap().get(columnId); DBType newColumn = newRecord.getColumnMap().get(columnId); newColumn = convertToExtendedColumn(oldColumn, newColumn, maxBlockSize, fileId, pinnedBlocks, new ColumnSerializerMetadata(type)); map.put(columnId, newColumn); } } int newRecordSize = RecordSerializer.getInstance().getRecordSize(oldRecord, meta); int availableSize = maxBlockSize - blockUsedSize - oldRecordSize; if (oldRecord instanceof ExtendedTableRecord) { } else { if (newRecordSize > availableSize) { List<BlockPtr> list = ExtendedUtils.getInstance().extend(fileId, pinnedBlocks); retRecord = new ExtendedTableRecord(oldRecord.getColumnMap(), list); retRecord.setRecordId(oldRecord.getRecordId()); } } return retRecord; } public DBType convertToExtendedColumn(DBType oldColumn, DBType newColumn, int maxBlockSize, byte fileId, Set<Object> pinnedBlocks, TypeMetadata meta) { int newColumnSize = ColumnSerializer.getInstance().getObjectSize(newColumn, meta); if (oldColumn instanceof ExtendedColumn) { if (newColumnSize < maxBlockSize) { ExtendedUtils.getInstance().releaseExtended((ExtendedColumn) oldColumn); return newColumn; } else { ((ExtendedColumn) oldColumn).setValue(newColumn); return oldColumn; } } else { if (newColumnSize >= maxBlockSize) { List<BlockPtr> ptrList = ExtendedUtils.getInstance().extend(fileId, pinnedBlocks); ExtendedColumn ec = new ExtendedColumn(newColumn, ptrList); return ec; } } return newColumn; } public ObjectRecord convertToExtended(ObjectRecord record, Set<Object> pinnedBlocks, TypeMetadata meta, int availableSize, byte fileId) { ObjectRecord retRecord = record; DBType column = record.getColumn(); int size = ColumnSerializer.getInstance().getObjectSize(column, meta); if (size >= availableSize) { List<BlockPtr> list = ExtendedUtils.getInstance().extend(fileId, pinnedBlocks); ExtendedColumn ec = new ExtendedColumn(column, list); retRecord.setColumn(ec); } return retRecord; } public int getConsumedResources(TableRecord record) { int consumedResources = 0; if (record instanceof Extended) { consumedResources = consumedResources + ((Extended) record).getPtrList().size(); } Iterator<DBType> iter = record.getColumnMap().values().iterator(); while (iter.hasNext()) { DBType c = iter.next(); if (c instanceof Extended) { consumedResources = consumedResources + ((Extended) c).getPtrList().size(); } } return consumedResources; } public int getConsumedResources(ObjectListRecord record) { int consumedResoures = 0; DBType c = record.getColumn(); if (c instanceof Extended) { consumedResoures = consumedResoures + ((Extended) c).getPtrList().size(); } return consumedResoures; } public int getConsumedResources(ListRecord record) { if (record instanceof TableRecord) { return getConsumedResources((TableRecord) record); } return getConsumedResources((ObjectListRecord) record); } public void mergeRecord(ListRecord oldRecord, ListRecord newRecord) { if (oldRecord instanceof IndexRecord) { IndexRecord iro = (IndexRecord) oldRecord; IndexRecord irn = (IndexRecord) newRecord; iro.setColumn(irn.getColumn()); return; } TableRecord tro = (TableRecord) oldRecord; TableRecord trn = (TableRecord) newRecord; Iterator<Integer> iter = trn.getColumnMap().keySet().iterator(); while (iter.hasNext()) { int colId = iter.next(); DBType newColumn = trn.getColumnMap().get(colId); DBType oldColumn = tro.getColumnMap().get(colId); if (oldColumn instanceof ExtendedColumn) { ((ExtendedColumn) oldColumn).setValue(newColumn); } else { tro.getColumnMap().put(colId, newColumn); } } } public void releaseRecord(Record record) { if (record instanceof TableRecord) { releaseTableRecord((TableRecord) record); } else if (record instanceof ObjectRecord) { releaseObjectRecord((ObjectListRecord) record); } } private void releaseTableRecord(TableRecord record) { Iterator<DBType> iter = record.getColumnMap().values().iterator(); while (iter.hasNext()) { DBType column = iter.next(); if (column instanceof Extended) { ExtendedUtils.getInstance().releaseExtended((Extended) column); } } if (record instanceof Extended) { ExtendedUtils.getInstance().releaseExtended((Extended) record); } } private void releaseObjectRecord(ObjectRecord record) { DBType column = record.getColumn(); if (column instanceof Extended) { ExtendedUtils.getInstance().releaseExtended((Extended) column); } } }