diff --git a/server/src/main/java/org/elasticsearch/index/fielddata/IndexFieldDataService.java b/server/src/main/java/org/elasticsearch/index/fielddata/IndexFieldDataService.java index a9d8df1cb26..25b03bcb250 100644 --- a/server/src/main/java/org/elasticsearch/index/fielddata/IndexFieldDataService.java +++ b/server/src/main/java/org/elasticsearch/index/fielddata/IndexFieldDataService.java @@ -97,7 +97,7 @@ public class IndexFieldDataService extends AbstractIndexComponent implements Clo final IndexFieldDataCache cache = fieldDataCaches.remove(fieldName); if (cache != null) { try { - cache.clear(); + cache.clear(fieldName); } catch (Exception e) { exceptions.add(e); } diff --git a/server/src/test/java/org/elasticsearch/index/fielddata/IndexFieldDataServiceTests.java b/server/src/test/java/org/elasticsearch/index/fielddata/IndexFieldDataServiceTests.java index b630558a216..2eba60a1a5f 100644 --- a/server/src/test/java/org/elasticsearch/index/fielddata/IndexFieldDataServiceTests.java +++ b/server/src/test/java/org/elasticsearch/index/fielddata/IndexFieldDataServiceTests.java @@ -100,6 +100,66 @@ public class IndexFieldDataServiceTests extends ESSingleNodeTestCase { assertTrue(fd instanceof SortedNumericDVIndexFieldData); } + public void testClearField() throws Exception { + final IndexService indexService = createIndex("test"); + final IndicesService indicesService = getInstanceFromNode(IndicesService.class); + // copy the ifdService since we can set the listener only once. + final IndexFieldDataService ifdService = new IndexFieldDataService(indexService.getIndexSettings(), + indicesService.getIndicesFieldDataCache(), indicesService.getCircuitBreakerService(), indexService.mapperService()); + + final BuilderContext ctx = new BuilderContext(indexService.getIndexSettings().getSettings(), new ContentPath(1)); + final MappedFieldType mapper1 = new TextFieldMapper.Builder("field_1").fielddata(true).build(ctx).fieldType(); + final MappedFieldType mapper2 = new TextFieldMapper.Builder("field_2").fielddata(true).build(ctx).fieldType(); + final IndexWriter writer = new IndexWriter(new RAMDirectory(), new IndexWriterConfig(new KeywordAnalyzer())); + Document doc = new Document(); + doc.add(new StringField("field_1", "thisisastring", Store.NO)); + doc.add(new StringField("field_2", "thisisanotherstring", Store.NO)); + writer.addDocument(doc); + final IndexReader reader = DirectoryReader.open(writer); + final AtomicInteger onCacheCalled = new AtomicInteger(); + final AtomicInteger onRemovalCalled = new AtomicInteger(); + ifdService.setListener(new IndexFieldDataCache.Listener() { + @Override + public void onCache(ShardId shardId, String fieldName, Accountable ramUsage) { + onCacheCalled.incrementAndGet(); + } + + @Override + public void onRemoval(ShardId shardId, String fieldName, boolean wasEvicted, long sizeInBytes) { + onRemovalCalled.incrementAndGet(); + } + }); + IndexFieldData ifd1 = ifdService.getForField(mapper1); + IndexFieldData ifd2 = ifdService.getForField(mapper2); + LeafReaderContext leafReaderContext = reader.getContext().leaves().get(0); + AtomicFieldData loadField1 = ifd1.load(leafReaderContext); + AtomicFieldData loadField2 = ifd2.load(leafReaderContext); + + assertEquals(2, onCacheCalled.get()); + assertEquals(0, onRemovalCalled.get()); + + ifdService.clearField("field_1"); + + assertEquals(2, onCacheCalled.get()); + assertEquals(1, onRemovalCalled.get()); + + ifdService.clearField("field_1"); + + assertEquals(2, onCacheCalled.get()); + assertEquals(1, onRemovalCalled.get()); + + ifdService.clearField("field_2"); + + assertEquals(2, onCacheCalled.get()); + assertEquals(2, onRemovalCalled.get()); + + reader.close(); + loadField1.close(); + loadField2.close(); + writer.close(); + ifdService.clear(); + } + public void testFieldDataCacheListener() throws Exception { final IndexService indexService = createIndex("test"); final IndicesService indicesService = getInstanceFromNode(IndicesService.class);