All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.scudata.dw.BlockLinkWriter Maven / Gradle / Ivy

Go to download

SPL(Structured Process Language) A programming language specially for structured data computing.

There is a newer version: 20240823
Show newest version
package com.scudata.dw;

import java.io.IOException;
import java.io.OutputStream;

public class BlockLinkWriter extends OutputStream {
	private static final double CompressThreshold = 0.75;//ѹ????ֵ
	private BlockLink blockLink;
	private IBlockStorage storage;
	
	private final int blockSize; // ???С
	private final int pointerPos; // ??һ??ָ???ڿ???λ??
	private byte []block; // ??????
	private int caret; // ????ڿ??е?λ??
	
	private LZ4Util lz4 = LZ4Util.instance();
	
	public BlockLinkWriter(BlockLink blockLink, boolean isAppend) throws IOException {
		this.blockLink = blockLink;
		storage = blockLink.getBlockStorage();
		
		blockSize = storage.getBlockSize();
		pointerPos = blockSize - IBlockStorage.POS_SIZE;
		caret = blockLink.getFreeIndex();
		block = new byte[blockSize];
		
		if (isAppend) {
			loadLastBlock();
		}
	}
	
	int getPointerPos() {
		return pointerPos;
	}
	
	private void loadLastBlock() throws IOException {
		storage.loadBlock(blockLink.lastBlockPos, block);
	}
	
	// ׷??д????Ҫ???ôκ???????д?IJ???Ҫ????
	public void finishWrite() throws IOException {
		blockLink.freeIndex = caret;
		storage.saveBlock(blockLink.lastBlockPos, block);
	}
	
	private void applyNewBlock() throws IOException {
		long nextBlock = storage.applyNewBlock();
		writePointer(pointerPos, nextBlock);
		storage.saveBlock(blockLink.lastBlockPos, block);
		writePointer(pointerPos, 0);//????Ҫclear
		blockLink.appendBlock(nextBlock);
		caret = 0;
	}
	
	public void write(int b) throws IOException {
		if (caret == pointerPos) {
			applyNewBlock();
		}
		
		block[caret++] = (byte)b;
	}
	
	public void writeInt32(int n) throws IOException {
		write(n >>> 24);
		write((n >>> 16) & 0xFF);
		write((n >>>  8) & 0xFF);
		write(n & 0xFF);
	}
	
	public void write(byte []buffer, int off, int len) throws IOException {
		int end = off + len;
		while (off < end) {
			int rest = end - off;
			int freeSize = pointerPos - caret;
			if (rest <= freeSize) {
				System.arraycopy(buffer, off, block, caret, rest);
				caret += rest;
				break;
			} else {
				System.arraycopy(buffer, off, block, caret, freeSize);
				applyNewBlock();
				off += freeSize;
			}
		}
	}
	
	// ׷?Ӳ?ѹ?????ݿ飬????д??λ??
	public long writeDataBlock(byte[] bytes) throws IOException {
		int srcCount = bytes.length;
		if (storage.isCompress()) {
			byte []buffer = lz4.compress(bytes);
			int count = lz4.getCount();
			long pos = blockLink.lastBlockPos + caret;
			
			if (((double)count / srcCount) < CompressThreshold) {
				writeInt32(srcCount);
				writeInt32(count);
				write(buffer, 0, count);
			} else {
				writeInt32(srcCount);
				writeInt32(0);
				write(bytes, 0, srcCount);
			}
			return pos;
		} else {
			long pos = blockLink.lastBlockPos + caret;
			writeInt32(srcCount);
			write(bytes, 0, srcCount);
			return pos;
		}
	}
	
	// ׷?????ݿ飬????д??λ?? (??ѹ??)
	public long writeDataBlock0(byte[] bytes) throws IOException {
		long pos = blockLink.lastBlockPos + caret;
		write(bytes);
		return pos;
	}
	
//	public long copyDataBlock(BlockLinkReader colReader) throws IOException {
//		int srcCount = colReader.readInt32();
//		int count = colReader.readInt32();
//		byte []buffer = new byte[count];
//		colReader.readFully(buffer, 0, count);
//		
//		long pos = blockLink.lastBlockPos + caret;
//		writeInt32(srcCount);
//		writeInt32(count);
//		write(buffer, 0, count);
//		return pos;
//	}
	
	// ????????????һ???λ??
	private long readPointer(int i) {
		byte []block = this.block;
		return (((long)(block[i] & 0xff) << 32) +
				((long)(block[i + 1] & 0xff) << 24) +
				((block[i + 2] & 0xff) << 16) +
				((block[i + 3] & 0xff) <<  8) +
				(block[i + 4] & 0xff));
	}
	
	// д??????????һ???λ??
	private void writePointer(int i, long pos) {
		byte []block = this.block;
		block[i++] = (byte)(pos >>> 32);
		block[i++] = (byte)(pos >>> 24);
		block[i++] = (byte)(pos >>> 16);
		block[i++] = (byte)(pos >>>  8);
		block[i++] = (byte)(pos >>>  0);
	}
	
	// ??д??????
	public void rewriteBlocks(byte[] bytes) throws IOException {
		int len = bytes.length;
		int oldBlockCount = blockLink.blockCount;
		
		long blockPos = blockLink.firstBlockPos;
		if (len <= pointerPos) {
			storage.saveBlock(blockPos, bytes);
		} else {
			int i = 0;
			while (i < len) {
				int rest = len - i;
				if (rest <= pointerPos) {
					storage.saveBlock(blockPos, bytes, i, rest);
					break;
				} else {
					storage.loadBlock(blockPos, block);
					long nextBlock = readPointer(pointerPos);
					if (oldBlockCount > 0) {
						oldBlockCount--;
					}
					if (nextBlock > blockPos && oldBlockCount > 0) {
						storage.saveBlock(blockPos, bytes, i, pointerPos);
					} else {
						System.arraycopy(bytes, i, block, 0, pointerPos);
						applyNewBlock();
						nextBlock = blockLink.lastBlockPos;
					}
					
					i += pointerPos;
					blockPos = nextBlock;
				}
			}
		}
	}
	
	// ׷?ӣ???ѹ?????ݿ飬????д??λ??
	public long writeDataBuffer(byte[] bytes) throws IOException {
		int count = bytes.length;
		long pos = blockLink.lastBlockPos + caret;
		
		writeInt32(count);
		write(bytes, 0, count);
		return pos;
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy