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 + -
显示快捷键?