package io.eguan.vvr.persistence.repository; /* * #%L * Project eguan * %% * Copyright (C) 2012 - 2017 Oodrive * %% * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * #L% */ import io.eguan.hash.HashAlgorithm; import io.eguan.nrs.NrsFile; import io.eguan.proto.vvr.VvrRemote; import io.eguan.proto.vvr.VvrRemote.RemoteOperation.Builder; import io.eguan.vvr.persistence.repository.NrsDevice.NrsDeviceImplHelper; import io.eguan.vvr.repository.core.api.BlockKeyLookupEx; import io.eguan.vvr.repository.core.api.DeviceReadWriteHandleImpl; import io.eguan.vvr.repository.core.api.Device.ReadWriteHandle; import java.io.IOException; import java.nio.ByteBuffer; /** * Implementation of a {@link ReadWriteHandle} storing blocks in the {@link NrsFile}. * * @author oodrive * @author llambert * */ final class NrsBlkDeviceReadWriteHandleImpl extends DeviceReadWriteHandleImpl { private static final int DUMMY_TXID = 55; NrsBlkDeviceReadWriteHandleImpl(final NrsDeviceImplHelper deviceImplHelper, final HashAlgorithm hashAlgorithm, final boolean readOnly, final int blockSize) { super(deviceImplHelper, hashAlgorithm, readOnly, blockSize); } @Override protected final int createBlockTransaction() throws IOException { // TODO real transaction return DUMMY_TXID; } @Override protected final void commitBlockTransaction(final int txId) throws IOException { assert txId == DUMMY_TXID; } @Override protected final void rollbackBlockTransaction(final int txId) throws IOException { assert txId == DUMMY_TXID; } @Override protected final boolean canReplaceOldKey() { // No replace here return false; } @Override protected final boolean needsBlockOpBuilder() { // Not yet return false; } @Override protected final void notifyBlockIO(final Builder blockOpBuilder) { // Should not get here (see previous method) throw new AssertionError(); } @Override protected final void storeNewBlock(final ByteBuffer block, final int offset, final long blockIndex, final byte[] newKey, final byte[] oldKey, final int txId, final VvrRemote.RemoteOperation.Builder opBuilder) throws IllegalArgumentException, IndexOutOfBoundsException, NullPointerException, IOException { assert txId == -1 || txId == DUMMY_TXID; assert opBuilder == null; // Write block to NrsBlockFile - no concurrent access to the block, as the block has been duplicated block.position(offset); block.limit(offset + blockSize); final NrsFile dstFile = ((NrsDeviceImplHelper) deviceImplHelper).getCurrentNrsFile(); dstFile.writeBlock(blockIndex, block); // Store key in persistence ((NrsDeviceImplHelper) deviceImplHelper).writeBlockKey(blockIndex, newKey); } @Override protected final ByteBuffer getBlock(final long blockIndex, final byte[] key, final BlockKeyLookupEx blockKeyLookupEx, final boolean readOnly) throws IOException, InterruptedException { final ByteBuffer data = allocateBlock(false); try { fillBlock(blockIndex, key, data, 0, blockKeyLookupEx); } catch (IOException | InterruptedException | RuntimeException | Error e) { releaseBlock(data); throw e; } return data; } @Override protected final void fillBlock(final long blockIndex, final byte[] key, final ByteBuffer data, final int dataOffset, final BlockKeyLookupEx blockKeyLookupEx) throws IOException, InterruptedException { // Write block to NrsBlockFile - no concurrent access to the block, as the block has been duplicated data.position(dataOffset); //data.limit(dataOffset + blockSize); final NrsFile nrsFileSource = ((NrsBlockKeyLookupEx) blockKeyLookupEx).getNrsFileSource(); nrsFileSource.readBlock(blockIndex, data); } }