Java tutorial
/* * Copyright 2014, Stratio. * * 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 com.stratio.cassandra.lucene; import com.google.common.base.Objects; import com.stratio.cassandra.lucene.schema.Schema; import com.stratio.cassandra.lucene.schema.SchemaBuilder; import org.apache.cassandra.config.CFMetaData; import org.apache.cassandra.config.DatabaseDescriptor; import java.io.File; import java.nio.file.Path; import java.nio.file.Paths; import java.util.Map; /** * The Stratio Lucene index user-specified configuration. * * @author Andres de la Pena {@literal <adelapena@stratio.com>} */ public class IndexConfig { public static final String SCHEMA_OPTION = "schema"; public static final String REFRESH_SECONDS_OPTION = "refresh_seconds"; public static final double DEFAULT_REFRESH_SECONDS = 60; public static final String DIRECTORY_PATH_OPTION = "directory_path"; public static final String INDEXES_DIR_NAME = "lucene"; public static final String RAM_BUFFER_MB_OPTION = "ram_buffer_mb"; public static final int DEFAULT_RAM_BUFFER_MB = 64; public static final String MAX_MERGE_MB_OPTION = "max_merge_mb"; public static final int DEFAULT_MAX_MERGE_MB = 5; public static final String MAX_CACHED_MB_OPTION = "max_cached_mb"; public static final int DEFAULT_MAX_CACHED_MB = 30; public static final String INDEXING_THREADS_OPTION = "indexing_threads"; public static final int DEFAULT_INDEXING_THREADS = 0; public static final String INDEXING_QUEUES_SIZE_OPTION = "indexing_queues_size"; public static final int DEFAULT_INDEXING_QUEUES_SIZE = 50; public static final String PAGING_CACHE_SIZE_OPTION = "paging_cache_size"; public static final int DEFAULT_PAGING_CACHE_SIZE = 100; private final Schema schema; private final double refreshSeconds; private final Path path; private final int ramBufferMB; private final int maxMergeMB; private final int maxCachedMB; private final int indexingThreads; private final int indexingQueuesSize; private final int pagingCacheSize; /** * Builds a new {@link IndexConfig} for the column family defined by the specified metadata using the specified * index options. * * @param metadata The metadata of the indexed column family. * @param options The index options. */ public IndexConfig(CFMetaData metadata, Map<String, String> options) { refreshSeconds = parseRefresh(options); ramBufferMB = parseRamBufferMB(options); maxMergeMB = parseMaxMergeMB(options); maxCachedMB = parseMaxCachedMB(options); indexingThreads = parseIndexingThreads(options); indexingQueuesSize = parseIndexingQueuesSize(options); schema = parseSchema(options, metadata); path = parsePath(options, metadata); pagingCacheSize = parsePagingCacheSize(options); } /** * Returns the {@link Schema} to be used. * * @return The {@link Schema} to be used. */ public Schema getSchema() { return schema; } /** * Returns the path of the directory where the Lucene files will be stored. This directory is collocated to the * indexed column family one. * * @return The path where the Lucene files will be stored. */ public Path getPath() { return path; } /** * Returns the number of seconds before refreshing the index readers. * * @return The number of seconds before refreshing the index readers. */ public double getRefreshSeconds() { return refreshSeconds; } /** * Returns the size of the Lucene index writer write buffer. Its content will be committed to disk when full. * * @return The size of the write buffer. */ public int getRamBufferMB() { return ramBufferMB; } public int getMaxMergeMB() { return maxMergeMB; } public int getMaxCachedMB() { return maxCachedMB; } /** * Returns the number of asynchronous indexing threads, where {@code 0} means synchronous indexing. * * @return The number of asynchronous indexing threads. */ public int getIndexingThreads() { return indexingThreads; } /** * Returns the max number of queued documents per asynchronous indexing thread. * * @return The max number of queued documents per asynchronous indexing thread. */ public int getIndexingQueuesSize() { return indexingQueuesSize; } /** * Returns the paging cache size. * * @return The paging cache size. */ public int getPagingCacheSize() { return pagingCacheSize; } private static double parseRefresh(Map<String, String> options) { String refreshOption = options.get(REFRESH_SECONDS_OPTION); double refreshSeconds; if (refreshOption != null) { try { refreshSeconds = Double.parseDouble(refreshOption); } catch (NumberFormatException e) { String msg = String.format("'%s' must be a strictly positive double", REFRESH_SECONDS_OPTION); throw new RuntimeException(msg); } if (refreshSeconds <= 0) { String msg = String.format("'%s' must be strictly positive", REFRESH_SECONDS_OPTION); throw new RuntimeException(msg); } else { return refreshSeconds; } } else { return DEFAULT_REFRESH_SECONDS; } } private static int parseRamBufferMB(Map<String, String> options) { String ramBufferSizeOption = options.get(RAM_BUFFER_MB_OPTION); int ramBufferMB; if (ramBufferSizeOption != null) { try { ramBufferMB = Integer.parseInt(ramBufferSizeOption); } catch (NumberFormatException e) { String msg = String.format("'%s' must be a strictly positive integer", RAM_BUFFER_MB_OPTION); throw new RuntimeException(msg); } if (ramBufferMB <= 0) { String msg = String.format("'%s' must be strictly positive", RAM_BUFFER_MB_OPTION); throw new RuntimeException(msg); } return ramBufferMB; } else { return DEFAULT_RAM_BUFFER_MB; } } private static int parseMaxMergeMB(Map<String, String> options) { String maxMergeSizeMBOption = options.get(MAX_MERGE_MB_OPTION); int maxMergeMB; if (maxMergeSizeMBOption != null) { try { maxMergeMB = Integer.parseInt(maxMergeSizeMBOption); } catch (NumberFormatException e) { String msg = String.format("'%s' must be a strictly positive integer", MAX_MERGE_MB_OPTION); throw new RuntimeException(msg); } if (maxMergeMB <= 0) { String msg = String.format("'%s' must be strictly positive", MAX_MERGE_MB_OPTION); throw new RuntimeException(msg); } return maxMergeMB; } else { return DEFAULT_MAX_MERGE_MB; } } private static int parseMaxCachedMB(Map<String, String> options) { String maxCachedMBOption = options.get(MAX_CACHED_MB_OPTION); int maxCachedMB; if (maxCachedMBOption != null) { try { maxCachedMB = Integer.parseInt(maxCachedMBOption); } catch (NumberFormatException e) { String msg = String.format("'%s' must be a strictly positive integer", MAX_CACHED_MB_OPTION); throw new RuntimeException(msg); } if (maxCachedMB <= 0) { String msg = String.format("'%s' must be strictly positive", MAX_CACHED_MB_OPTION); throw new RuntimeException(msg); } return maxCachedMB; } else { return DEFAULT_MAX_CACHED_MB; } } private static int parseIndexingThreads(Map<String, String> options) { String indexPoolNumQueuesOption = options.get(INDEXING_THREADS_OPTION); int indexingThreads; if (indexPoolNumQueuesOption != null) { try { indexingThreads = Integer.parseInt(indexPoolNumQueuesOption); } catch (NumberFormatException e) { String msg = String.format("'%s' must be a positive integer", INDEXING_THREADS_OPTION); throw new RuntimeException(msg); } return indexingThreads; } else { return DEFAULT_INDEXING_THREADS; } } private static int parseIndexingQueuesSize(Map<String, String> options) { String indexPoolQueuesSizeOption = options.get(INDEXING_QUEUES_SIZE_OPTION); int indexingQueuesSize; if (indexPoolQueuesSizeOption != null) { try { indexingQueuesSize = Integer.parseInt(indexPoolQueuesSizeOption); } catch (NumberFormatException e) { String msg = String.format("'%s' must be a strictly positive integer", INDEXING_QUEUES_SIZE_OPTION); throw new RuntimeException(msg); } if (indexingQueuesSize <= 0) { String msg = String.format("'%s' must be strictly positive", INDEXING_QUEUES_SIZE_OPTION); throw new RuntimeException(msg); } return indexingQueuesSize; } else { return DEFAULT_INDEXING_QUEUES_SIZE; } } private static Schema parseSchema(Map<String, String> options, CFMetaData metadata) { String schemaOption = options.get(SCHEMA_OPTION); Schema schema; if (schemaOption != null && !schemaOption.trim().isEmpty()) { try { schema = SchemaBuilder.fromJson(schemaOption).build(); schema.validate(metadata); } catch (Exception e) { String msg = String.format("'%s' is invalid : %s", SCHEMA_OPTION, e.getMessage()); throw new RuntimeException(msg); } return schema; } else { String msg = String.format("'%s' required", SCHEMA_OPTION); throw new RuntimeException(msg); } } private static Path parsePath(Map<String, String> options, CFMetaData metadata) { String pathOption = options.get(DIRECTORY_PATH_OPTION); if (pathOption == null) { String pathString = DatabaseDescriptor.getAllDataFileLocations()[0] + File.separatorChar + metadata.ksName + File.separatorChar + metadata.cfName + "-" + metadata.cfId + File.separatorChar + INDEXES_DIR_NAME; return Paths.get(pathString); } else { return Paths.get(pathOption); } } private static int parsePagingCacheSize(Map<String, String> options) { String pagingCacheSizeOption = options.get(PAGING_CACHE_SIZE_OPTION); int pagingCacheSize; if (pagingCacheSizeOption != null) { try { pagingCacheSize = Integer.parseInt(pagingCacheSizeOption); } catch (NumberFormatException e) { String msg = String.format("'%s' must be a positive integer", PAGING_CACHE_SIZE_OPTION); throw new RuntimeException(msg); } return pagingCacheSize; } else { return DEFAULT_PAGING_CACHE_SIZE; } } /** {@inheritDoc} */ @Override public String toString() { return Objects.toStringHelper(this).add("schema", schema).add("refreshSeconds", refreshSeconds) .add("path", path).add("ramBufferMB", ramBufferMB).add("maxMergeMB", maxMergeMB) .add("maxCachedMB", maxCachedMB).add("indexingThreads", indexingThreads) .add("indexingQueuesSize", indexingQueuesSize).toString(); } }