store.java

来自「RESIN 3.2 最新源码」· Java 代码 · 共 1,996 行 · 第 1/4 页

JAVA
1,996
字号
  {    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_MINI_FRAG && fragMask != 0xff) {	    allocationTable[i + 1] = (byte) 0xff;	    setAllocDirty(i + 1, i + 2);	    _miniFragmentUseCount++;	    long fragmentAddress	      = BLOCK_SIZE * ((long) i / ALLOC_BYTES_PER_BLOCK);	    	    return fragmentAddress;	  }	}      }      // if no fragment, allocate a new one.            Block block = allocateMiniFragmentBlock();      block.free();    }  }    /**   * Deletes a miniFragment.   */  public void deleteMiniFragment(StoreTransaction xa, long fragmentAddress)    throws IOException  {    Block block = readBlock(fragmentAddress);    try {      int fragIndex = (int) (fragmentAddress & BLOCK_OFFSET_MASK);      int offset = fragIndex / 8 + MINI_FRAG_ALLOC_OFFSET;      int mask = 1 << (fragIndex % 8);      byte []blockBuffer = block.getBuffer();      synchronized (blockBuffer) {	blockBuffer[offset] &= ~mask;	block.setDirty(offset, offset + 1);	  	int i = (int) (ALLOC_BYTES_PER_BLOCK * (fragmentAddress / BLOCK_SIZE));	int j = (int) (fragmentAddress & 0xff);	synchronized (_allocationLock) {	  int fragMask = _allocationTable[i + 1] & 0xff;	  //System.out.println((fragmentAddress / BLOCK_SIZE) + ":" + j + " DELETE");	  if (_allocationTable[i] != ALLOC_MINI_FRAG)	    System.out.println("BAD ENTRY: " + fragMask);	  _allocationTable[i + 1] = 0;	  _miniFragmentUseCount--;		  setAllocDirty(i + 1, i + 2);	}      }    } finally {      block.free();    }  }    /**   * Writes a miniFragment.   *   * @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 writeMiniFragment(StoreTransaction xa,			    long fragmentAddress, int fragmentOffset,			    byte []buffer, int offset, int length)    throws IOException  {    if (MINI_FRAG_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.addUpdateBlock(block);            int blockOffset = getMiniFragmentOffset(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 miniFragmentAddress 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 writeMiniFragment(StoreTransaction xa,			    long fragmentAddress, int fragmentOffset,			    char []buffer, int offset, int length)    throws IOException  {    if (MINI_FRAG_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 = getMiniFragmentOffset(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 miniFragment.   *   * @return the long value   */  public void writeMiniFragmentLong(StoreTransaction xa,				    long fragmentAddress, int fragmentOffset,				    long value)    throws IOException  {    Block block = xa.readBlock(this, addressToBlockId(fragmentAddress));    try {      xa.addUpdateBlock(block);            int blockOffset = getMiniFragmentOffset(fragmentAddress);      byte []blockBuffer = block.getBuffer();      int offset = blockOffset + fragmentOffset;      synchronized (blockBuffer) {	writeLong(blockBuffer, offset, value);	block.setDirty(offset, offset + 8);      }    } finally {      block.free();    }  }  /**   * Returns the miniFragment offset for an id.   */  private int getMiniFragmentOffset(long fragmentAddress)  {    int id = (int) (fragmentAddress & BLOCK_OFFSET_MASK);    return (int) (MINI_FRAG_SIZE * id);  }  /**   * Reads a block into the buffer.   */  public void readBlock(long blockId, byte []buffer, int offset, int length)    throws IOException  {    synchronized (_fileLock) {      RandomAccessWrapper wrapper = openRowFile();      RandomAccessStream is = wrapper.getFile();      long blockAddress = blockId & BLOCK_MASK;      try {	if (blockAddress < 0 || _fileSize < blockAddress + length) {	  throw new IllegalStateException(L.l("block at {0} is invalid for file {1} (length {2})",					      Long.toHexString(blockAddress),					      _path,					      Long.toHexString(_fileSize)));	}	//System.out.println("READ: " + (blockAddress >> 16) + ":" + (blockAddress & 0xffff));	int readLen = is.read(blockAddress, buffer, offset, length);	if (readLen < 0) {	  for (int i = 0; i < BLOCK_SIZE; i++)	    buffer[i] = 0;	}      	freeRowFile(wrapper);	wrapper = null;      } finally {	if (wrapper != null)	  wrapper.close();      }    }  }  /**   * Saves the buffer to the database.   */  public void writeBlock(long blockAddress,			 byte []buffer, int offset, int length)    throws IOException  {    synchronized (_fileLock) {      RandomAccessWrapper wrapper = openRowFile();      RandomAccessStream os = wrapper.getFile();          try {	os.write(blockAddress, buffer, offset, length);      	freeRowFile(wrapper);	wrapper = null;      	if (_fileSize < blockAddress + length) {	  _fileSize = blockAddress + length;	}            } finally {	if (wrapper != null)	  wrapper.close();      }    }  }  /**   * Opens the underlying file to the database.   */  private RandomAccessWrapper openRowFile()    throws IOException  {    RandomAccessStream file = null;    RandomAccessWrapper wrapper = null;        synchronized (this) {      SoftReference<RandomAccessWrapper> ref = _cachedRowFile;      _cachedRowFile = null;            if (ref != null) {	wrapper = ref.get();      }    }    if (wrapper != null)      file = wrapper.getFile();    if (file == null) {      file = _path.openRandomAccess();      wrapper = new RandomAccessWrapper(file);    }    return wrapper;  }  private void freeRowFile(RandomAccessWrapper wrapper)    throws IOException  {    synchronized (this) {      if (_cachedRowFile == null) {	_cachedRowFile = new SoftReference<RandomAccessWrapper>(wrapper);	return;      }    }    wrapper.close();  }  /**   * Writes the short.   */  private static void writeShort(byte []buffer, int offset, int v)  {    buffer[offset + 0] = (byte) (v >> 8);    buffer[offset + 1] = (byte) (v);  }  /**   * Reads a short.   */  private static int readShort(byte []buffer, int offset)  {    return (((buffer[offset + 0] & 0xff) << 8) |	    ((buffer[offset + 1] & 0xff)));  }  /**   * Flush the store.   */  public void flush()  {    if (_lifecycle.isActive()) {      if (_blockManager != null) {	_blockManager.flush(this);      }    }  }  /**   * True if destroyed.   */  public boolean isClosed()  {    return _lifecycle.isDestroyed();  }    /**   * Closes the store.   */  public void close()  {    if (! _lifecycle.toDestroy())      return;    log.finer(this + " closing");    if (_blockManager != null) {      _blockManager.freeStore(this);      _blockManager.freeStoreId(_id);    }    long id = _id;    _id = 0;    _path = null;        RandomAccessWrapper wrapper = null;        SoftReference<RandomAccessWrapper> ref = _cachedRowFile;    _cachedRowFile = null;          if (ref != null)      wrapper = ref.get();    if (wrapper != null) {      try {	wrapper.close();      } catch (Throwable e) {      }    }  }  // debugging stuff.  /**   * Returns a copy of the allocation table.   */  public byte []getAllocationTable()  {    byte []table = new byte[_allocationTable.length];    System.arraycopy(_allocationTable, 0, table, 0, table.length);    return table;  }  private static IllegalStateException stateError(String msg)  {    IllegalStateException e = new IllegalStateException(msg);    e.fillInStackTrace();    log.log(Level.WARNING, e.toString(), e);    return e;  }  /**   * Reads the long.   */  public static long readLong(byte []buffer, int offset)  {    return (((buffer[offset + 0] & 0xffL) << 56) +	    ((buffer[offset + 1] & 0xffL) << 48) +	    ((buffer[offset + 2] & 0xffL) << 40) +	    ((buffer[offset + 3] & 0xffL) << 32) +	    ((buffer[offset + 4] & 0xffL) << 24) +	    ((buffer[offset + 5] & 0xffL) << 16) +	    ((buffer[offset + 6] & 0xffL) << 8) +	    ((buffer[offset + 7] & 0xffL)));  }  /**   * Writes the long.   */  public static void writeLong(byte []buffer, int offset, long v)  {    buffer[offset + 0] = (byte) (v >> 56);    buffer[offset + 1] = (byte) (v >> 48);    buffer[offset + 2] = (byte) (v >> 40);    buffer[offset + 3] = (byte) (v >> 32);        buffer[offset + 4] = (byte) (v >> 24);    buffer[offset + 5] = (byte) (v >> 16);    buffer[offset + 6] = (byte) (v >> 8);    buffer[offset + 7] = (byte) (v);  }  /**   * Debug names for the allocation.   */  public static String codeToName(int code)  {    switch (code) {    case ALLOC_FREE:      return "free";    case ALLOC_ROW:      return "row";    case ALLOC_USED:      return "used";    case ALLOC_FRAGMENT:      return "fragment";    case ALLOC_MINI_FRAG:      return "mini-fragment";    case ALLOC_INDEX:      return "index";    default:      return String.valueOf(code);    }  }    public String toString()  {    return "Store[" + _id + "]";  }  static class RandomAccessWrapper {    private RandomAccessStream _file;    RandomAccessWrapper(RandomAccessStream file)    {      _file = file;    }    RandomAccessStream getFile()    {      return _file;    }    void close()      throws IOException    {      RandomAccessStream file = _file;      _file = null;      if (file != null)	file.close();    }    protected void finalize()      throws Throwable    {      super.finalize();            close();    }  }}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?