blob: a6226492ae60b352d93be98f5a84fb64ab568e34 [file] [log] [blame]
/**
* 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;
import static org.apache.blur.utils.BlurConstants.BLUR_SHARD_BLOCKCACHE_DIRECT_MEMORY_ALLOCATION;
import static org.apache.blur.utils.BlurConstants.BLUR_SHARD_BLOCKCACHE_SLAB_COUNT;
import java.io.IOException;
import java.util.Set;
import org.apache.blur.BlurConfiguration;
import org.apache.blur.log.Log;
import org.apache.blur.log.LogFactory;
import org.apache.blur.store.blockcache.BlockCache;
import org.apache.blur.store.blockcache.BlockDirectory;
import org.apache.blur.store.blockcache.BlockDirectoryCache;
import org.apache.blur.store.blockcache.Cache;
import org.apache.lucene.store.Directory;
public class BlockCacheDirectoryFactoryV1 extends BlockCacheDirectoryFactory {
private static final Log LOG = LogFactory.getLog(BlockCacheDirectoryFactoryV1.class);
private final Cache _cache;
public BlockCacheDirectoryFactoryV1(BlurConfiguration configuration, long totalNumberOfBytes) {
// setup block cache
// 134,217,728 is the slab size, therefore there are 16,384 blocks
// in a slab when using a block size of 8,192
int numberOfBlocksPerSlab = 16384;
int blockSize = BlockDirectory.BLOCK_SIZE;
int slabCount = configuration.getInt(BLUR_SHARD_BLOCKCACHE_SLAB_COUNT, -1);
slabCount = getSlabCount(slabCount, numberOfBlocksPerSlab, blockSize, totalNumberOfBytes);
Cache cache;
if (slabCount >= 1) {
BlockCache blockCache;
boolean directAllocation = configuration.getBoolean(BLUR_SHARD_BLOCKCACHE_DIRECT_MEMORY_ALLOCATION, true);
int slabSize = numberOfBlocksPerSlab * blockSize;
LOG.info("Number of slabs of block cache [{0}] with direct memory allocation set to [{1}]", slabCount,
directAllocation);
LOG.info("Block cache target memory usage, slab size of [{0}] will allocate [{1}] slabs and use ~[{2}] bytes",
slabSize, slabCount, ((long) slabCount * (long) slabSize));
try {
long totalMemory = (long) slabCount * (long) numberOfBlocksPerSlab * (long) blockSize;
blockCache = new BlockCache(directAllocation, totalMemory, slabSize);
} catch (OutOfMemoryError e) {
if ("Direct buffer memory".equals(e.getMessage())) {
System.err
.println("The max direct memory is too low. Either increase by setting (-XX:MaxDirectMemorySize=<size>g -XX:+UseLargePages) or disable direct allocation by (blur.shard.blockcache.direct.memory.allocation=false) in blur-site.properties");
System.exit(1);
}
throw e;
}
cache = new BlockDirectoryCache(blockCache);
} else {
cache = BlockDirectory.NO_CACHE;
}
_cache = cache;
}
@Override
public Directory newDirectory(String table, String shard, Directory directory, Set<String> blockCacheFileTypes)
throws IOException {
return new BlockDirectory(table + "_" + shard, directory, _cache, blockCacheFileTypes);
}
private static int getSlabCount(int slabCount, int numberOfBlocksPerSlab, int blockSize, long totalNumberOfBytes) {
if (slabCount < 0) {
long slabSize = numberOfBlocksPerSlab * blockSize;
if (totalNumberOfBytes < slabSize) {
throw new RuntimeException("Auto slab setup cannot happen, JVM option -XX:MaxDirectMemorySize not set.");
}
return (int) (totalNumberOfBytes / slabSize);
}
return slabCount;
}
@Override
public void close() throws IOException {
}
}