DataFragment.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 gnu.trove.list.array.TIntArrayList;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInput;
import java.io.DataInputStream;
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.ArrayList;
import java.util.List;
/**
*
* @author zoly
*/
final class DataFragment {
private long location;
private long nextDataFragment;
private final long startTimeMillis;
private List<long[]> data;
private TIntArrayList timestamps;
public DataFragment(final long startTimeMillis) {
this.location = 0;
this.nextDataFragment = 0;
this.startTimeMillis = startTimeMillis;
data = new ArrayList<long[]>();
timestamps = new TIntArrayList();
}
public DataFragment(final RandomAccessFile raf) throws IOException {
location = raf.getFilePointer();
FileChannel ch = raf.getChannel();
FileLock lock = ch.lock(location, 8, true);
try {
this.nextDataFragment = raf.readLong();
this.startTimeMillis = raf.readLong();
int nrSamples = raf.readInt();
int samplesLength = raf.readInt();
int bufferSize = nrSamples * (samplesLength * 8 + 4);
byte [] buffer = new byte [bufferSize];
raf.readFully(buffer);
loadData(nrSamples, samplesLength, new DataInputStream(new ByteArrayInputStream(buffer)));
} finally {
lock.release();
}
}
public void writeTo(final DataOutput dos) throws IOException {
dos.writeLong(nextDataFragment);
dos.writeLong(startTimeMillis);
dos.writeInt(data.size());
dos.writeInt(data.get(0).length);
for (int i = 0; i < timestamps.size(); i++) {
dos.writeInt(timestamps.get(i));
for (long value : data.get(i)) {
dos.writeLong(value);
}
}
}
public 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 void addData(final long timestamp, final long [] dataRow) {
data.add(dataRow);
timestamps.add((int) (timestamp - startTimeMillis));
}
public void setNextDataFragment(final long pnextDataFragment, final RandomAccessFile raf) throws IOException {
this.nextDataFragment = pnextDataFragment;
setNextDataFragment(location, nextDataFragment, raf);
}
public static void setNextDataFragment(final long dataFragmentPosition, final long nextDataFragment,
final RandomAccessFile raf) throws IOException {
FileChannel ch = raf.getChannel();
FileLock lock = ch.lock(dataFragmentPosition, 8, false);
try {
raf.seek(dataFragmentPosition);
raf.writeLong(nextDataFragment);
} finally {
lock.release();
}
}
public long getNextDataFragment() {
return nextDataFragment;
}
public long getLocation() {
return location;
}
private void loadData(final int nrSamples, final int samplesLength, final DataInput raf) throws IOException {
data = new ArrayList(nrSamples);
timestamps = new TIntArrayList(nrSamples);
for (int i = 0; i < nrSamples; i++) {
timestamps.add(raf.readInt());
long [] row = new long[samplesLength];
for (int j = 0; j < samplesLength; j++) {
row[j] = raf.readLong();
}
data.add(row);
}
}
public long getStartTimeMillis() {
return startTimeMillis;
}
public int getNrRows() {
return data.size();
}
public List<long[]> getData() {
return data;
}
public TIntArrayList getTimestamps() {
return timestamps;
}
public void setLocation(final long location) {
this.location = location;
}
@Override
public String toString() {
return "DataFragment{" + "location=" + location + ", nextDataFragment=" + nextDataFragment
+ ", startTimeMillis=" + startTimeMillis + ", data=" + data + ", timestamps=" + timestamps + '}';
}
}