/* * Licensed to ElasticSearch and Shay Banon under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. ElasticSearch 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.elasticsearch.index.cache; import org.apache.lucene.index.IndexReader; import org.elasticsearch.ElasticSearchException; import org.elasticsearch.cluster.ClusterChangedEvent; import org.elasticsearch.cluster.ClusterService; import org.elasticsearch.cluster.ClusterStateListener; import org.elasticsearch.common.Nullable; import org.elasticsearch.common.component.CloseableComponent; import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.unit.TimeValue; import org.elasticsearch.index.AbstractIndexComponent; import org.elasticsearch.index.Index; import org.elasticsearch.index.cache.bloom.BloomCache; import org.elasticsearch.index.cache.field.data.FieldDataCache; import org.elasticsearch.index.cache.filter.FilterCache; import org.elasticsearch.index.cache.id.IdCache; import org.elasticsearch.index.cache.query.parser.QueryParserCache; import org.elasticsearch.index.settings.IndexSettings; /** * */ public class IndexCache extends AbstractIndexComponent implements CloseableComponent, ClusterStateListener { private final FilterCache filterCache; private final FieldDataCache fieldDataCache; private final QueryParserCache queryParserCache; private final IdCache idCache; private final BloomCache bloomCache; private final TimeValue refreshInterval; private ClusterService clusterService; private long latestCacheStatsTimestamp = -1; private CacheStats latestCacheStats; @Inject public IndexCache(Index index, @IndexSettings Settings indexSettings, FilterCache filterCache, FieldDataCache fieldDataCache, QueryParserCache queryParserCache, IdCache idCache, BloomCache bloomCache) { super(index, indexSettings); this.filterCache = filterCache; this.fieldDataCache = fieldDataCache; this.queryParserCache = queryParserCache; this.idCache = idCache; this.bloomCache = bloomCache; this.refreshInterval = componentSettings.getAsTime("stats.refresh_interval", TimeValue.timeValueSeconds(1)); logger.debug("Using stats.refresh_interval [{}]", refreshInterval); } @Inject(optional = true) public void setClusterService(@Nullable ClusterService clusterService) { this.clusterService = clusterService; if (clusterService != null) { clusterService.add(this); } } public synchronized void invalidateCache() { FilterCache.EntriesStats filterEntriesStats = filterCache.entriesStats(); latestCacheStats = new CacheStats(fieldDataCache.evictions(), filterCache.evictions(), fieldDataCache.sizeInBytes(), filterEntriesStats.sizeInBytes, filterEntriesStats.count, bloomCache.sizeInBytes(), idCache.sizeInBytes()); latestCacheStatsTimestamp = System.currentTimeMillis(); } public synchronized CacheStats stats() { long timestamp = System.currentTimeMillis(); if ((timestamp - latestCacheStatsTimestamp) > refreshInterval.millis()) { FilterCache.EntriesStats filterEntriesStats = filterCache.entriesStats(); latestCacheStats = new CacheStats(fieldDataCache.evictions(), filterCache.evictions(), fieldDataCache.sizeInBytes(), filterEntriesStats.sizeInBytes, filterEntriesStats.count, bloomCache.sizeInBytes(), idCache.sizeInBytes()); latestCacheStatsTimestamp = timestamp; } return latestCacheStats; } public FilterCache filter() { return filterCache; } public FieldDataCache fieldData() { return fieldDataCache; } public IdCache idCache() { return this.idCache; } public BloomCache bloomCache() { return this.bloomCache; } public QueryParserCache queryParserCache() { return this.queryParserCache; } @Override public void close() throws ElasticSearchException { filterCache.close(); fieldDataCache.close(); idCache.close(); queryParserCache.close(); bloomCache.close(); if (clusterService != null) { clusterService.remove(this); } } public void clear(IndexReader reader) { filterCache.clear(reader); fieldDataCache.clear(reader); idCache.clear(reader); bloomCache.clear(reader); } public void clear(String reason) { filterCache.clear(reason); fieldDataCache.clear(reason); idCache.clear(); queryParserCache.clear(); bloomCache.clear(); } @Override public void clusterChanged(ClusterChangedEvent event) { // clear the query parser cache if the metadata (mappings) changed... if (event.metaDataChanged()) { queryParserCache.clear(); } } }