All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.inbot.elasticsearch.crud.GuavaCachingChildCrudDao Maven / Gradle / Ivy

package io.inbot.elasticsearch.crud;



import com.codahale.metrics.Metric;
import com.github.jsonj.JsonObject;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import io.inbot.elasticsearch.bulkindexing.BulkIndexerStatusHandler;
import io.inbot.elasticsearch.bulkindexing.BulkIndexingOperations;
import io.inbot.elasticsearch.client.IterableSearchResponse;
import io.inbot.elasticsearch.client.PagedSearchResponse;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.function.Function;

public class GuavaCachingChildCrudDao implements ParentChildCrudOperations {

    private final ParentChildCrudOperations crudDao;
    private LoadingCache> cache;

    private static class ParentChild {
        public final String parent;
        public final String child;

        public ParentChild(String parent, String child) {
            this.parent = parent;
            this.child = child;
        }

        public static ParentChild from(String parent, String child) {
            return new ParentChild(parent, child);
        }
    }

    public GuavaCachingChildCrudDao(ParentChildCrudOperations crudDao, int maxItems, int expireAfterWriteSeconds) {
        this.crudDao = crudDao;
        cache = CacheBuilder.newBuilder()
                .expireAfterWrite(expireAfterWriteSeconds, TimeUnit.SECONDS)
                .maximumSize(maxItems)
                .softValues().build(new CacheLoader>() {

                    @Override
                    public Optional load(ParentChild key) throws Exception {
                        JsonObject object = crudDao.get(false, key.child, key.parent);
                        if(object == null) {
                            return Optional.empty();
                        } else {
                            return Optional.of(object);
                        }
                    }
                });
    }

    @Override
    public Map getMetrics() {
        Map metrics = new HashMap<>();
        metrics.putAll(crudDao.getMetrics());
        return metrics;
    }

    @Override
    public JsonObject create(JsonObject object, String parentId, boolean replace) {
        JsonObject created = crudDao.create(object, parentId, false);
        cache.put(ParentChild.from(parentId, created.getString("id")), Optional.of(object));
        return created;
    }

    @Override
    public Set recentlyModifiedIds(String parentId) {
        return crudDao.recentlyModifiedIds(parentId);
    }

    @Override
    public JsonObject update(String id, boolean modifyUpdatedAt, Function f, String parentId) {
        JsonObject updated = crudDao.update(id, true, f, parentId);
        cache.put(ParentChild.from(parentId, id), Optional.of(updated));
        return updated;
    }

    @Override
    public JsonObject get(String id, String parentId) {
        try {
            Optional maybeValue = cache.get(ParentChild.from(parentId, id));
            if(maybeValue.isPresent()) {
                return maybeValue.get().deepClone();
            } else {
                return null;
            }
        } catch (ExecutionException e) {
            throw new IllegalStateException("unexpected error fetching value from cache", e);
        }
    }

    @Override
    public JsonObject get(boolean cached, String id, String parentId) {
        if(cached) {
            return get(id,parentId);
        } else {
            return crudDao.get(cached, id, parentId);
        }
    }

    @Override
    public void delete(String id, String parentId) {
        crudDao.delete(id, parentId);
        cache.invalidate(ParentChild.from(parentId, id));
    }

    @Override
    public PagedSearchResponse pagedSearch(JsonObject q, int size, int from) {
        PagedSearchResponse results = crudDao.pagedSearch(q, size, from);
        return results;
    }

    @Override
    public IterableSearchResponse iterableSearch(JsonObject q, int pageSize, int ttlMinutes, boolean rawResults) {
        IterableSearchResponse results = crudDao.iterableSearch(q, pageSize, ttlMinutes, rawResults);
        return results;
    }

    @Override
    public JsonObject searchUnique(JsonObject q) {
        JsonObject result = crudDao.searchUnique(q);
        return result;
    }

    @Override
    public BulkIndexingOperations bulkIndexer() {
        BulkIndexingOperations bulkIndexer = crudDao.bulkIndexer();

        BulkIndexingOperations cacheUpdatingBulkIndexer = new BulkIndexingOperations() {

            @Override
            public void close() throws IOException {
                bulkIndexer.close();
            }

            @Override
            public void update(String id, String version, String parentId, JsonObject object, Function transformFunction) {
                bulkIndexer.update(id, version, parentId, object, transformFunction);
                cache.put(ParentChild.from(parentId, id), Optional.of(object));
            }

            @Override
            public void setBulkIndexerStatusHandler(BulkIndexerStatusHandler statusHandler) {
                bulkIndexer.setBulkIndexerStatusHandler(statusHandler);
            }

            @Override
            public void index(String id, String type, String parentId, String version, JsonObject object) {
                bulkIndexer.index(id, type, parentId, version, object);
                cache.put(ParentChild.from(parentId, id), Optional.of(object));
            }

            @Override
            public void index(JsonObject o, String parentId) {
                bulkIndexer.index(o, parentId);
                cache.put(ParentChild.from(parentId, o.getString("id")), Optional.of(o));
            }

            @Override
            public void index(JsonObject o) {
                throw new UnsupportedOperationException("parentId required");
            }

            @Override
            public void delete(String id) {
                throw new UnsupportedOperationException("parentId required");
            }

            @Override
            public void delete(String id, String parentId) {
                bulkIndexer.delete(id);
                cache.invalidate(ParentChild.from(parentId, id));
            }

            @Override
            public void flush() {
                bulkIndexer.flush();
            }

            @Override
            public void setRefresh(boolean b) {
                bulkIndexer.setRefresh(b);
            }
        };

        return cacheUpdatingBulkIndexer;
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy