/* * Copyright 2015 the original author or authors. * @https://github.com/scouter-project/scouter * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package scouter.server.db.io.zip; public class Block { public String date; public int blockNum; private byte buf[]; public final int START; public int END; public final int MAX; public boolean dirty; public long lastAccessTime; public Block(String date) { this(date, GZipCtr.BLOCK_MAX_SIZE); } public Block(String date, int max) { this(date, new byte[128], 0, 0, max); } public Block(String date, byte[] buf, int max) { this(date, buf, 0, buf.length, max); } public Block(String date, byte[] buf, int start, int end, int max) { this.date = date; this.buf = buf; this.START = start; this.END = end; this.MAX = max; } private void ensureCapacity(int minCapacity) { if (minCapacity > buf.length) { int oldCapacity = buf.length; int newCapacity = oldCapacity << 1; if (newCapacity < minCapacity) newCapacity = minCapacity; newCapacity = Math.min(newCapacity, MAX); buf = copyOf(buf, newCapacity); } } private static byte[] copyOf(byte[] org, int length) { byte[] copy = new byte[length]; System.arraycopy(org, 0, copy, 0, Math.min(org.length, length)); return copy; } public boolean write(byte[] b) { return write(b, 0, b.length); } public synchronized boolean write(byte[] b, int offset, int len) { if (END + len > MAX) return false; ensureCapacity(END - START + len); System.arraycopy(b, offset, buf, END - START, len); END += len; this.dirty=true; return true; } public synchronized byte[] read(long pos, int len) { if(len<=0) return null; int bpos = (int) (pos - (blockNum * GZipCtr.BLOCK_MAX_SIZE)); if (len + bpos > END) return null; if (bpos < START) return null; byte[] out = new byte[len]; System.arraycopy(this.buf, bpos - START, out, 0, len); return out; } public long getOffset() { return (long) END + ((long) blockNum) * GZipCtr.BLOCK_MAX_SIZE; } public byte[] getBlockBytes() { byte[] out = new byte[this.END-this.START]; System.arraycopy(this.buf, 0, out, 0, this.END-this.START); return out; } public Block createNextBlock() { Block bk = new Block(date, MAX); bk.blockNum = this.blockNum + 1; return bk; } public boolean readable(long pos) { int bpos = (int) (pos - (blockNum * GZipCtr.BLOCK_MAX_SIZE)); if (8 + bpos > END) return false; if (bpos < START) return false; return true; } public Block merge(Block old) { int start = Math.min(this.START, old.START); int end = Math.max(this.END, old.END); byte[] block = new byte[end - start]; System.arraycopy(this.buf, 0, block, this.START -start, this.END - this.START); System.arraycopy(old.buf, 0, block, old.START - start, old.END - old.START); Block b= new Block(this.date, block, start, end, this.MAX); b.blockNum=this.blockNum; return b; } @Override public String toString() { return "Block [date=" + date + ", blockNum=" + blockNum + ", START=" + START + ", END=" + END + ", MAX=" + MAX + ", dirty=" + dirty + "]"; } }