Пример #1
0
  @Override
  public <A> void recordUpdate(long recid, A value, Serializer<A> serializer) {
    try {
      DataOutput2 out = new DataOutput2();
      serializer.serialize(out, value);

      if (CC.ASSERT && out.pos > 1 << 16) throw new InternalError("Record bigger then 64KB");
      try {
        writeLock_lock();

        // check if size has changed
        final long oldIndexVal = index.getLong(recid * 8);
        final long oldSize = oldIndexVal >>> 48;
        if (oldSize == 0 && out.pos == 0) {
          // do nothing
        }
        if (oldSize == out.pos) {
          // size is the same, so just write new data
          phys.putData(oldIndexVal & PHYS_OFFSET_MASK, out);
        } else if (oldSize != 0 && out.pos == 0) {
          // new record has zero size, just delete old phys one
          freePhysRecPut(oldIndexVal);
          index.putLong(recid * 8, 0L);
        } else {
          // size has changed, so write into new location
          final long newIndexValue = freePhysRecTake(out.pos);
          phys.putData(newIndexValue & PHYS_OFFSET_MASK, out);
          // update index file with new location
          index.putLong(recid * 8, newIndexValue);

          // and set old phys record as free
          if (oldSize != 0) freePhysRecPut(oldIndexVal);
        }
      } finally {
        writeLock_unlock();
      }
    } catch (IOException e) {
      throw new IOError(e);
    }
  }
Пример #2
0
  @Override
  public <A> long recordPut(A value, Serializer<A> serializer) {
    try {
      DataOutput2 out = new DataOutput2();
      serializer.serialize(out, value);
      if (CC.ASSERT && out.pos > 1 << 16) throw new InternalError("Record bigger then 64KB");

      try {
        writeLock_lock();
        // update index file, find free recid
        long recid = longStackTake(RECID_FREE_INDEX_SLOTS);
        if (recid == 0) {
          // could not reuse recid, so create new one
          final long indexSize = index.getLong(RECID_CURRENT_INDEX_FILE_SIZE * 8);
          if (CC.ASSERT && indexSize % 8 != 0) throw new InternalError();
          recid = indexSize / 8;
          // grow buffer if necessary
          index.ensureAvailable(indexSize + 8);
          index.putLong(RECID_CURRENT_INDEX_FILE_SIZE * 8, indexSize + 8);
        }

        // get physical record
        // first 16 bites is record size, remaining 48 bytes is record offset in phys file
        final long indexValue = out.pos != 0 ? freePhysRecTake(out.pos) : 0L;

        phys.putData(indexValue & PHYS_OFFSET_MASK, out);
        index.putLong(recid * 8, indexValue);

        return recid;
      } finally {
        writeLock_unlock();
      }
    } catch (IOException e) {
      throw new IOError(e);
    }
  }