store.java
来自「RESIN 3.2 最新源码」· Java 代码 · 共 1,996 行 · 第 1/4 页
JAVA
1,996 行
} finally { block.free(); } } /** * Allocates a new fragment. * * @return the fragment address */ public long allocateFragment(StoreTransaction xa) throws IOException { while (true) { synchronized (_allocationLock) { byte []allocationTable = _allocationTable; for (int i = 0; i < allocationTable.length; i += ALLOC_BYTES_PER_BLOCK) { int fragMask = allocationTable[i + 1] & 0xff; if (allocationTable[i] == ALLOC_FRAGMENT && fragMask != 0xff) { for (int j = 0; j < FRAGMENT_PER_BLOCK; j++) { if ((fragMask & (1 << j)) == 0) { allocationTable[i + 1] = (byte) (fragMask | (1 << j)); setAllocDirty(i + 1, i + 2); _fragmentUseCount++; long fragmentAddress = BLOCK_SIZE * ((long) i / ALLOC_BYTES_PER_BLOCK) + j; //System.out.println((fragmentAddress / BLOCK_SIZE) + ":" + j + " ALLOCATE"); return fragmentAddress; } } } } } // if no fragment, allocate a new one. Block block = allocateFragmentBlock(); block.free(); } } /** * Deletes a fragment. */ public void deleteFragment(StoreTransaction xa, long fragmentAddress) throws IOException { synchronized (_allocationLock) { int i = (int) (ALLOC_BYTES_PER_BLOCK * (fragmentAddress / BLOCK_SIZE)); int j = (int) (fragmentAddress & 0xff); int fragMask = _allocationTable[i + 1] & 0xff; //System.out.println((fragmentAddress / BLOCK_SIZE) + ":" + j + " DELETE"); if (_allocationTable[i] != ALLOC_FRAGMENT) System.out.println("BAD ENTRY: " + fragMask); if (j >= 8) System.out.println("BAD J: " + fragMask); if ((fragMask & (1 << j)) == 0) { log.fine("BAD J-MASK: " + fragMask + " " + j); } _allocationTable[i + 1] = (byte) (fragMask & ~(1 << j)); _fragmentUseCount--; setAllocDirty(i + 1, i + 2); } } /** * Writes a fragment. * * @param xa the owning transaction * @param fragmentAddress the fragment to write * @param fragmentOffset the offset into the fragment * @param buffer the write buffer * @param offset offset into the write buffer * @param length the number of bytes to write * * @return the fragment id */ public void writeFragment(StoreTransaction xa, long fragmentAddress, int fragmentOffset, byte []buffer, int offset, int length) throws IOException { if (FRAGMENT_SIZE - fragmentOffset < length) throw new IllegalArgumentException(L.l("write offset {0} length {1} too long", fragmentOffset, length)); Block block = xa.readBlock(this, addressToBlockId(fragmentAddress)); try { xa.addUpdateFragmentBlock(block); int blockOffset = getFragmentOffset(fragmentAddress); byte []blockBuffer = block.getBuffer(); blockOffset += fragmentOffset; synchronized (blockBuffer) { System.arraycopy(buffer, offset, blockBuffer, blockOffset, length); block.setDirty(blockOffset, blockOffset + length); } } finally { block.free(); } } /** * Writes a character based * * @param fragmentAddress the fragment to write * @param fragmentOffset the offset into the fragment * @param buffer the write buffer * @param offset offset into the write buffer * @param length the number of bytes to write */ public void writeFragment(StoreTransaction xa, long fragmentAddress, int fragmentOffset, char []buffer, int offset, int length) throws IOException { if (FRAGMENT_SIZE - fragmentOffset < length) throw new IllegalArgumentException(L.l("write offset {0} length {1} too long", fragmentOffset, length)); Block block = xa.readBlock(this, addressToBlockId(fragmentAddress)); try { block = xa.createAutoCommitWriteBlock(block); int blockOffset = getFragmentOffset(fragmentAddress); byte []blockBuffer = block.getBuffer(); blockOffset += fragmentOffset; synchronized (blockBuffer) { int blockTail = blockOffset; for (int i = 0; i < length; i++) { char ch = buffer[offset + i]; blockBuffer[blockTail] = (byte) (ch >> 8); blockBuffer[blockTail + 1] = (byte) (ch); blockTail += 2; } block.setDirty(blockOffset, blockTail); } } finally { block.free(); } } /** * Writes a long value to a fragment. * * @return the long value */ public void writeFragmentLong(StoreTransaction xa, long fragmentAddress, int fragmentOffset, long value) throws IOException { Block block = xa.readBlock(this, addressToBlockId(fragmentAddress)); try { xa.addUpdateBlock(block); int blockOffset = getFragmentOffset(fragmentAddress); byte []blockBuffer = block.getBuffer(); int offset = blockOffset + fragmentOffset; synchronized (blockBuffer) { writeLong(blockBuffer, offset, value); block.setDirty(offset, offset + 8); } } finally { block.free(); } } /** * Writes a blockfragment. * * @param xa the owning transaction * @param blockAddress the block to write * @param blockOffset the offset into the block * @param buffer the write buffer * @param offset offset into the write buffer * @param length the number of bytes to write * * @return the fragment id */ public void writeBlock(StoreTransaction xa, long blockAddress, int blockOffset, byte []buffer, int offset, int length) throws IOException { if (BLOCK_SIZE - blockOffset < length) throw new IllegalArgumentException(L.l("write offset {0} length {1} too long", blockOffset, length)); Block block = xa.readBlock(this, addressToBlockId(blockAddress)); try { xa.addUpdateBlock(block); byte []blockBuffer = block.getBuffer(); synchronized (blockBuffer) { System.arraycopy(buffer, offset, blockBuffer, blockOffset, length); block.setDirty(blockOffset, blockOffset + length); } } finally { block.free(); } } /** * Writes a character based block * * @param blockAddress the fragment to write * @param blockOffset the offset into the fragment * @param buffer the write buffer * @param offset offset into the write buffer * @param length the number of bytes to write */ public void writeBlock(StoreTransaction xa, long blockAddress, int blockOffset, char []buffer, int offset, int length) throws IOException { if (BLOCK_SIZE - blockOffset < length) throw new IllegalArgumentException(L.l("write offset {0} length {1} too long", blockOffset, length)); Block block = xa.readBlock(this, addressToBlockId(blockAddress)); try { block = xa.createAutoCommitWriteBlock(block); byte []blockBuffer = block.getBuffer(); synchronized (blockBuffer) { int blockTail = blockOffset; for (int i = 0; i < length; i++) { char ch = buffer[offset + i]; blockBuffer[blockTail] = (byte) (ch >> 8); blockBuffer[blockTail + 1] = (byte) (ch); blockTail += 2; } block.setDirty(blockOffset, blockTail); } } finally { block.free(); } } /** * Writes a long value to a block * * @return the long value */ public void writeBlockLong(StoreTransaction xa, long blockAddress, int offset, long value) throws IOException { Block block = xa.readBlock(this, addressToBlockId(blockAddress)); try { xa.addUpdateBlock(block); byte []blockBuffer = block.getBuffer(); synchronized (blockBuffer) { writeLong(blockBuffer, offset, value); block.setDirty(offset, offset + 8); } } finally { block.free(); } } /** * Returns the fragment offset for an id. */ private int getFragmentOffset(long fragmentAddress) { int id = (int) (fragmentAddress & BLOCK_OFFSET_MASK); return (int) (FRAGMENT_SIZE * id); } /** * Reads a fragment. * * @param fragmentAddress the address of the fragment * @param fragmentOffset the offset inside the fragment to start reading * @param buffer the result buffer * @param offset offset into the result buffer * @param length the number of bytes to read * * @return the number of bytes read */ public int readMiniFragment(long fragmentAddress, int fragmentOffset, byte []buffer, int offset, int length) throws IOException { if (MINI_FRAG_SIZE - fragmentOffset < length) { throw new IllegalArgumentException(L.l("read offset {0} length {1} too long", fragmentOffset, length)); } Block block = readBlock(addressToBlockId(fragmentAddress)); try { int blockOffset = getMiniFragmentOffset(fragmentAddress); byte []blockBuffer = block.getBuffer(); synchronized (blockBuffer) { System.arraycopy(blockBuffer, blockOffset + fragmentOffset, buffer, offset, length); } return length; } finally { block.free(); } } /** * Reads a miniFragment for a clob. * * @param fragmentAddress the address of the fragment * @param fragmentOffset the offset inside the fragment to start reading * @param buffer the result buffer * @param offset offset into the result buffer * @param length the length of the fragment in characters * * @return the number of characters read */ public int readMiniFragment(long fragmentAddress, int fragmentOffset, char []buffer, int offset, int length) throws IOException { if (MINI_FRAG_SIZE - fragmentOffset < 2 * length) { throw new IllegalArgumentException(L.l("read offset {0} length {1} too long", fragmentOffset, length)); } Block block = readBlock(addressToBlockId(fragmentAddress)); try { int blockOffset = getMiniFragmentOffset(fragmentAddress); blockOffset += fragmentOffset; byte []blockBuffer = block.getBuffer(); synchronized (blockBuffer) { for (int i = 0; i < length; i++) { int ch1 = blockBuffer[blockOffset] & 0xff; int ch2 = blockBuffer[blockOffset + 1] & 0xff; buffer[offset + i] = (char) ((ch1 << 8) + ch2); blockOffset += 2; } } return length; } finally { block.free(); } } /** * Reads a long value from a miniFragment. * * @return the long value */ public long readMiniFragmentLong(long fragmentAddress, int fragmentOffset) throws IOException { Block block = readBlock(addressToBlockId(fragmentAddress)); try { int blockOffset = getMiniFragmentOffset(fragmentAddress); byte []blockBuffer = block.getBuffer(); synchronized (blockBuffer) { return readLong(blockBuffer, blockOffset + fragmentOffset); } } finally { block.free(); } } /** * Allocates a new miniFragment. * * @return the fragment address */ public long allocateMiniFragment(StoreTransaction xa) throws IOException { while (true) { long blockAddr = allocateMiniFragmentBlock(xa); Block block = readBlock(blockAddr); int fragOffset = -1; try { byte []blockBuffer = block.getBuffer(); synchronized (blockBuffer) { for (int i = 0; i < MINI_FRAG_PER_BLOCK; i++) { int offset = i / 8 + MINI_FRAG_ALLOC_OFFSET; int mask = 1 << (i % 8); if ((blockBuffer[offset] & mask) == 0) { fragOffset = i; blockBuffer[offset] |= mask; block.setDirty(offset, offset + 1); break; } } // fragment allocated underneath us if (fragOffset < 0) continue; boolean hasFree = false; for (int i = 0; i < MINI_FRAG_PER_BLOCK; i++) { int offset = i / 8 + MINI_FRAG_ALLOC_OFFSET; int mask = 1 << (i % 8); if ((blockBuffer[offset] & mask) == 0) { hasFree = true; break; } } if (hasFree) { int i = (int) (ALLOC_BYTES_PER_BLOCK * (blockAddr / BLOCK_SIZE)); synchronized (_allocationLock) { _allocationTable[i + 1] = 0; setAllocDirty(i + 1, i + 2); } } return blockAddr + fragOffset; } } finally { block.free(); } } } /** * Allocates a new miniFragment. * * @return the fragment address */ private long allocateMiniFragmentBlock(StoreTransaction xa) throws IOException
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?