@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); } }
@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); } }