@Override
    public void initCache(TableDefinition tableDefinition, SiddhiAppContext siddhiAppContext,
                          StreamEventCloner storeEventCloner, ConfigReader configReader) {
        String[] annotationNames = {ANNOTATION_STORE, ANNOTATION_CACHE};
        Annotation cacheTableAnnotation = getAnnotation(annotationNames, tableDefinition.getAnnotations());
        if (cacheTableAnnotation != null) {
            cacheEnabled = true;
            maxCacheSize = Integer.parseInt(cacheTableAnnotation.getElement(CACHE_TABLE_SIZE));
            TableDefinition cacheTableDefinition = TableDefinition.id(tableDefinition.getId());
            for (Attribute attribute : tableDefinition.getAttributeList()) {
                cacheTableDefinition.attribute(attribute.getName(), attribute.getType());
            }
            for (Annotation annotation : tableDefinition.getAnnotations()) {
                if (!annotation.getName().equalsIgnoreCase("Store")) {
                    cacheTableDefinition.annotation(annotation);
                }
            }

            String cachePolicy = cacheTableAnnotation.getElement(ANNOTATION_CACHE_POLICY);

            if (cachePolicy == null || cachePolicy.equalsIgnoreCase("FIFO")) {
                cachePolicy = "FIFO";
                cacheTable = new CacheTableFIFO();
            } else if (cachePolicy.equalsIgnoreCase("LRU")) {
                cacheTable = new CacheTableLRU();
            } else if (cachePolicy.equalsIgnoreCase("LFU")) {
                cacheTable = new CacheTableLFU();
            } else {
                throw new SiddhiAppCreationException(siddhiAppContext.getName() + " : Cache policy can only be one " +
                        "of FIFO, LRU, and LFU but given as " + cachePolicy);
            }

            // check if cache expiry enabled and initialize relevant parameters
            if (cacheTableAnnotation.getElement(ANNOTATION_CACHE_RETENTION_PERIOD) != null) {
                cacheExpiryEnabled = true;
                retentionPeriod = Expression.Time.timeToLong(cacheTableAnnotation.
                        getElement(ANNOTATION_CACHE_RETENTION_PERIOD));
                if (cacheTableAnnotation.getElement(ANNOTATION_CACHE_PURGE_INTERVAL) == null) {
                    purgeInterval = retentionPeriod;
                } else {
                    purgeInterval = Expression.Time.timeToLong(cacheTableAnnotation.
                            getElement(ANNOTATION_CACHE_PURGE_INTERVAL));
                }
                storeSizeCheckInterval = purgeInterval * 5;
            } else {
                storeSizeCheckInterval = 10000;
            }

            ((CacheTable) cacheTable).initCacheTable(cacheTableDefinition, configReader, siddhiAppContext,
                    recordTableHandler, cacheExpiryEnabled, maxCacheSize, cachePolicy);

            // creating objects needed to load cache
            SiddhiQueryContext siddhiQueryContext = new SiddhiQueryContext(siddhiAppContext,
                    CACHE_QUERY_NAME + tableDefinition.getId());
            MatchingMetaInfoHolder matchingMetaInfoHolder =
                    generateMatchingMetaInfoHolderForCacheTable(tableDefinition);
            OnDemandQuery onDemandQuery = OnDemandQuery.query().
                    from(
                            InputStore.store(tableDefinition.getId())).
                    select(
                            Selector.selector().
                                    limit(Expression.value((maxCacheSize + 1)))
                    );
            List<VariableExpressionExecutor> variableExpressionExecutors = new ArrayList<>();

            compiledConditionForCaching = compileCondition(Expression.value(true), matchingMetaInfoHolder,
                    variableExpressionExecutors, tableMap, siddhiQueryContext);
            List<Attribute> expectedOutputAttributes = buildExpectedOutputAttributes(onDemandQuery,
                    tableMap, SiddhiConstants.UNKNOWN_STATE, matchingMetaInfoHolder, siddhiQueryContext);

            compiledSelectionForCaching = compileSelection(onDemandQuery.getSelector(), expectedOutputAttributes,
                    matchingMetaInfoHolder, variableExpressionExecutors, tableMap, siddhiQueryContext);

            outputAttributesForCaching = expectedOutputAttributes.toArray(new Attribute[0]);
            QueryParserHelper.reduceMetaComplexEvent(matchingMetaInfoHolder.getMetaStateEvent());
            QueryParserHelper.updateVariablePosition(matchingMetaInfoHolder.getMetaStateEvent(),
                    variableExpressionExecutors);
            compiledSelectionForSelectAll = generateCSForSelectAll();
        }
    }
An abstract implementation of table. Abstract implementation will handle {@link ComplexEventChunk} so that
developer can directly work with event data.
modules/siddhi-core/src/main/java/io/siddhi/core/table/record/AbstractQueryableRecordTable.java