blob: ad10357fec51f23680d4e86ec7a36baed20b9b56 [file] [log] [blame]
package org.apache.solr.store.blockcache;
/*
* 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.
*/
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
/**
* @lucene.experimental
*/
public class BufferStore implements Store {
private static final Store EMPTY = new Store() {
@Override
public byte[] takeBuffer(int bufferSize) {
return new byte[bufferSize];
}
@Override
public void putBuffer(byte[] buffer) {
}
};
private final static ConcurrentMap<Integer, BufferStore> bufferStores = new ConcurrentHashMap<>();
private final BlockingQueue<byte[]> buffers;
private final int bufferSize;
public synchronized static void initNewBuffer(int bufferSize, long totalAmount) {
if (totalAmount == 0) {
return;
}
BufferStore bufferStore = bufferStores.get(bufferSize);
if (bufferStore == null) {
long count = totalAmount / bufferSize;
if (count > Integer.MAX_VALUE) {
count = Integer.MAX_VALUE;
}
BufferStore store = new BufferStore(bufferSize, (int) count);
bufferStores.put(bufferSize, store);
}
}
private BufferStore(int bufferSize, int count) {
this.bufferSize = bufferSize;
buffers = setupBuffers(bufferSize, count);
}
private static BlockingQueue<byte[]> setupBuffers(int bufferSize, int count) {
BlockingQueue<byte[]> queue = new ArrayBlockingQueue<>(count);
for (int i = 0; i < count; i++) {
queue.add(new byte[bufferSize]);
}
return queue;
}
public static Store instance(int bufferSize) {
BufferStore bufferStore = bufferStores.get(bufferSize);
if (bufferStore == null) {
return EMPTY;
}
return bufferStore;
}
@Override
public byte[] takeBuffer(int bufferSize) {
if (this.bufferSize != bufferSize) {
throw new RuntimeException("Buffer with length [" + bufferSize + "] does not match buffer size of ["
+ bufferSize + "]");
}
return newBuffer(buffers.poll());
}
@Override
public void putBuffer(byte[] buffer) {
if (buffer == null) {
return;
}
if (buffer.length != bufferSize) {
throw new RuntimeException("Buffer with length [" + buffer.length + "] does not match buffer size of ["
+ bufferSize + "]");
}
checkReturn(buffers.offer(buffer));
}
private void checkReturn(boolean offer) {
}
private byte[] newBuffer(byte[] buf) {
if (buf != null) {
return buf;
}
return new byte[bufferSize];
}
}