ColumnInfo.java
/*
* Copyright (c) 2001, Zoltan Farkas All Rights Reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
package org.spf4j.perf.tsdb;
import java.io.ByteArrayOutputStream;
import java.io.DataOutput;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.channels.FileChannel;
import java.nio.channels.FileLock;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
/**
*
* @author zoly
*/
public final class ColumnInfo {
private final long location;
private long nextColumnInfo;
private long firstDataFragment;
private long lastDataFragment;
private final String groupName;
private final int sampleTime;
private final byte[] groupMetaData;
private final String [] columnNames;
private final byte [][] columnMetaData;
private final Map<String, Integer> nameToIndex;
ColumnInfo(final String groupName, final byte [] groupMetaData,
final String [] columnNames, final byte [][] columnMetaData,
final int sampleTime, final long location) {
this.location = location;
this.nextColumnInfo = 0;
this.firstDataFragment = 0;
this.lastDataFragment = 0;
this.groupName = groupName;
this.sampleTime = sampleTime;
this.groupMetaData = groupMetaData;
this.columnNames = columnNames;
this.columnMetaData = columnMetaData;
this.nameToIndex = new HashMap<String, Integer>(columnNames.length + columnNames.length / 3);
for (int i = 0; i < columnNames.length; i++) {
this.nameToIndex.put(columnNames[i], i);
}
}
ColumnInfo(final RandomAccessFile raf) throws IOException {
location = raf.getFilePointer();
FileChannel ch = raf.getChannel();
FileLock lock = ch.lock(location, 8, true);
try {
this.nextColumnInfo = raf.readLong();
this.firstDataFragment = raf.readLong();
this.lastDataFragment = raf.readLong();
this.groupName = raf.readUTF();
this.sampleTime = raf.readInt();
int grMetaSize = raf.readInt();
this.groupMetaData = new byte [grMetaSize];
raf.readFully(groupMetaData);
int nrColumns = raf.readShort();
columnNames = new String[nrColumns];
this.nameToIndex = new HashMap<String, Integer>(nrColumns + nrColumns / 3);
for (int i = 0; i < columnNames.length; i++) {
String colName = raf.readUTF();
columnNames[i] = colName;
this.nameToIndex.put(colName, i);
}
columnMetaData = new byte[raf.readInt()][];
for (int i = 0; i < columnMetaData.length; i++) {
int metaLength = raf.readInt();
byte [] colMetaData = new byte[metaLength];
raf.readFully(colMetaData);
columnMetaData[i] = colMetaData;
}
} finally {
lock.release();
}
}
void writeTo(final DataOutput dos) throws IOException {
dos.writeLong(nextColumnInfo);
dos.writeLong(firstDataFragment);
dos.writeLong(lastDataFragment);
dos.writeUTF(groupName);
dos.writeInt(sampleTime);
dos.writeInt(groupMetaData.length);
dos.write(groupMetaData);
dos.writeShort(columnNames.length);
for (String columnName : columnNames) {
dos.writeUTF(columnName);
}
dos.writeInt(columnMetaData.length);
for (byte[] colMeta : columnMetaData) {
dos.writeInt(colMeta.length);
dos.write(colMeta);
}
}
void writeTo(final RandomAccessFile raf) throws IOException {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
DataOutput dos = new DataOutputStream(bos);
writeTo(dos);
FileChannel ch = raf.getChannel();
FileLock lock = ch.lock(raf.getFilePointer(), 8, false);
try {
raf.seek(location);
raf.write(bos.toByteArray());
} finally {
lock.release();
}
}
public String [] getColumnNames() {
return columnNames.clone();
}
void setNextColumnInfo(final long pnextColumnInfo, final RandomAccessFile raf) throws IOException {
this.nextColumnInfo = pnextColumnInfo;
FileChannel ch = raf.getChannel();
FileLock lock = ch.lock(location, 8, false);
try {
raf.seek(location);
raf.writeLong(nextColumnInfo);
} finally {
lock.release();
}
}
void setFirstDataFragment(final long pfirstDataFragment, final RandomAccessFile raf) throws IOException {
this.firstDataFragment = pfirstDataFragment;
FileChannel ch = raf.getChannel();
FileLock lock = ch.lock(location + 8, 8, false);
try {
raf.seek(location + 8);
raf.writeLong(firstDataFragment);
} finally {
lock.release();
}
}
void setLastDataFragment(final long plastDataFragment, final RandomAccessFile raf) throws IOException {
this.lastDataFragment = plastDataFragment;
FileChannel ch = raf.getChannel();
FileLock lock = ch.lock(raf.getFilePointer() + 16, 8, false);
try {
raf.seek(location + 16);
raf.writeLong(lastDataFragment);
} finally {
lock.release();
}
}
public long getNextColumnInfo() {
return nextColumnInfo;
}
public long getLocation() {
return location;
}
public String getGroupName() {
return groupName;
}
public long getFirstDataFragment() {
return firstDataFragment;
}
public long getLastDataFragment() {
return lastDataFragment;
}
public byte[][] getColumnMetaData() {
return columnMetaData.clone();
}
public int getColumnIndex(final String columnName) {
Integer result = this.nameToIndex.get(columnName);
if (result == null) {
return -1;
} else {
return result;
}
}
public int getSampleTime() {
return sampleTime;
}
public byte[] getGroupMetaData() {
return groupMetaData.clone();
}
public int getColumnNumber() {
return columnNames.length;
}
public String getColumnName(final int index) {
return columnNames[index];
}
@Override
public String toString() {
return "ColumnInfo{" + "location=" + location + ", nextColumnInfo=" + nextColumnInfo
+ ", firstDataFragment=" + firstDataFragment + ", lastDataFragment="
+ lastDataFragment + ", groupName=" + groupName + ", sampleTime=" + sampleTime
+ ", columnNames=" + Arrays.toString(columnNames) + ", nameToIndex=" + nameToIndex + '}';
}
}