/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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 org.apache.blur.store.blockcache_v2.cachevalue;
import static org.apache.blur.metrics.MetricsConstants.CACHE_VALUE_FINALIZE;
import static org.apache.blur.metrics.MetricsConstants.JVM;
import static org.apache.blur.metrics.MetricsConstants.ORG_APACHE_BLUR;
import java.util.concurrent.atomic.AtomicLong;
import org.apache.blur.metrics.AtomicLongGauge;
import org.apache.blur.store.blockcache_v2.CacheValue;
import org.apache.blur.store.blockcache_v2.EvictionException;
import com.yammer.metrics.Metrics;
import com.yammer.metrics.core.MetricName;
public abstract class BaseCacheValue implements CacheValue {
private static final AtomicLong _neededFinalizedCall = new AtomicLong();
protected final int _length;
protected volatile boolean _released = false;
protected volatile boolean _evicted = false;
static {
Metrics.newGauge(new MetricName(ORG_APACHE_BLUR, JVM, CACHE_VALUE_FINALIZE), new AtomicLongGauge(
_neededFinalizedCall));
}
public BaseCacheValue(int length) {
_length = length;
}
@Override
public final int length() {
return _length;
}
@Override
public void write(int position, byte[] buf, int offset, int length) {
if (position + length > _length) {
throw new ArrayIndexOutOfBoundsException(position + length);
}
writeInternal(position, buf, offset, length);
}
private void checkForEviction() throws EvictionException {
if (_evicted) {
throw new EvictionException();
}
}
@Override
public void read(int position, byte[] buf, int offset, int length) throws EvictionException {
checkForEviction();
if (position + length > _length) {
throw new ArrayIndexOutOfBoundsException(position + length);
}
readInternal(position, buf, offset, length);
}
@Override
public byte read(int position) throws EvictionException {
checkForEviction();
if (position >= _length) {
throw new ArrayIndexOutOfBoundsException(position);
}
return readInternal(position);
}
@Override
public short readShort(int position) throws EvictionException {
checkForEviction();
if (position + 2 > _length) {
throw new ArrayIndexOutOfBoundsException(position + 2);
}
return readShortInternal(position);
}
protected short readShortInternal(int position) {
return (short) (((readInternal(position) & 0xFF) << 8) | (readInternal(position + 1) & 0xFF));
}
@Override
public int readInt(int position) throws EvictionException {
checkForEviction();
if (position + 4 > _length) {
throw new ArrayIndexOutOfBoundsException(position + 4);
}
return readIntInternal(position);
}
protected int readIntInternal(int position) {
return ((readInternal(position) & 0xFF) << 24) | ((readInternal(position + 1) & 0xFF) << 16)
| ((readInternal(position + 2) & 0xFF) << 8) | (readInternal(position + 3) & 0xFF);
}
@Override
public long readLong(int position) throws EvictionException {
checkForEviction();
if (position + 8 > _length) {
throw new ArrayIndexOutOfBoundsException(position + 4);
}
return readLongInternal(position);
}
protected long readLongInternal(int position) {
return (((long) readIntInternal(position)) << 32) | (readIntInternal(position + 4) & 0xFFFFFFFFL);
}
protected abstract void writeInternal(int position, byte[] buf, int offset, int length);
protected abstract byte readInternal(int position);
protected abstract void readInternal(int position, byte[] buf, int offset, int length);
@Override
public CacheValue trim(int length) {
return this;
}
@Override
public CacheValue detachFromCache() {
throw new RuntimeException("Not implemented.");
}
@Override
public final boolean isEvicted() {
return _evicted;
}
}