/***********************************************************************************************************************
*
* Copyright (C) 2010 by the Stratosphere project (http://stratosphere.eu)
*
* 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.
*
**********************************************************************************************************************/
package eu.stratosphere.nephele.io.compression;
import java.io.IOException;
import eu.stratosphere.nephele.io.channels.Buffer;
import eu.stratosphere.nephele.io.channels.MemoryBuffer;
import eu.stratosphere.nephele.taskmanager.bufferprovider.BufferProvider;
import eu.stratosphere.nephele.util.StringUtils;
public final class CompressionBufferProvider {
private final int maximumBufferSize;
private MemoryBuffer compressionBuffer;
private MemoryBuffer temporaryBuffer;
private boolean compressionBufferLocked = false;
private boolean temporaryBufferLocked = false;
private int referenceCounter = 1;
public CompressionBufferProvider(final BufferProvider bufferProvider, boolean allocateTempBuffer) {
this.maximumBufferSize = bufferProvider.getMaximumBufferSize();
try {
final Buffer buf = bufferProvider.requestEmptyBuffer(this.maximumBufferSize);
if (buf == null) {
throw new IllegalStateException("Cannot retrieve compression buffer");
}
if (!buf.isBackedByMemory()) {
throw new IllegalStateException("Compression buffer is not backed by memory");
}
this.compressionBuffer = (MemoryBuffer) buf;
} catch (IOException ioe) {
throw new RuntimeException(StringUtils.stringifyException(ioe));
}
if (allocateTempBuffer) {
try {
final Buffer buf = bufferProvider.requestEmptyBuffer(this.maximumBufferSize);
if (buf == null) {
throw new IllegalStateException("Cannot retrieve temporary buffer");
}
if (!buf.isBackedByMemory()) {
throw new IllegalStateException("Temporary buffer is not backed by memory");
}
this.temporaryBuffer = (MemoryBuffer) buf;
} catch (IOException ioe) {
throw new RuntimeException(StringUtils.stringifyException(ioe));
}
} else {
this.temporaryBuffer = null;
}
}
public void increaseReferenceCounter() {
++this.referenceCounter;
}
public int getMaximumBufferSize() {
return this.maximumBufferSize;
}
public MemoryBuffer lockCompressionBuffer() {
if (this.compressionBufferLocked) {
throw new IllegalStateException("Compression buffer is already locked");
}
this.compressionBufferLocked = true;
return this.compressionBuffer;
}
public MemoryBuffer lockTemporaryBuffer() {
if (this.temporaryBuffer == null) {
throw new IllegalStateException("No temporary buffer allocated, so it cannot be locked");
}
if (this.temporaryBufferLocked) {
throw new IllegalStateException("Temporary buffer is already locked");
}
this.temporaryBufferLocked = true;
return this.temporaryBuffer;
}
public void releaseCompressionBuffer(final MemoryBuffer compressionBuffer) {
if (!this.compressionBufferLocked) {
throw new IllegalStateException("Compression buffer is not locked");
}
this.compressionBuffer = compressionBuffer;
this.compressionBufferLocked = false;
}
public void releaseTemporaryBuffer(final MemoryBuffer temporaryBuffer) {
if (!this.temporaryBufferLocked) {
throw new IllegalStateException("Temporary buffer is not locked");
}
this.temporaryBuffer = temporaryBuffer;
this.temporaryBufferLocked = false;
}
public void shutdown() {
--this.referenceCounter;
if (this.referenceCounter > 0) {
return;
}
if (this.compressionBufferLocked) {
throw new IllegalStateException("Shutdown requested but compression buffer is still locked");
}
if (this.compressionBuffer != null) {
this.compressionBuffer.recycleBuffer();
this.compressionBuffer = null;
}
if (this.temporaryBufferLocked) {
throw new IllegalStateException("Shutdown requested but temporary buffer is still locked " +
this.temporaryBuffer);
}
if (this.temporaryBuffer != null) {
this.temporaryBuffer.recycleBuffer();
this.temporaryBuffer = null;
}
}
}