/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF 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.apache.jackrabbit.oak.plugins.document.cache;

import com.google.common.base.Predicate;
import com.google.common.hash.BloomFilter;
import com.google.common.hash.Funnel;
import com.google.common.hash.PrimitiveSink;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.Closeable;
import java.util.List;

public class CacheChangesTracker implements Closeable {

    private static final Logger LOG = LoggerFactory.getLogger(CacheChangesTracker.class);

    static final int ENTRIES_SCOPED = 1000;

    static final int ENTRIES_OPEN = 10000;

    private final List<CacheChangesTracker> changeTrackers;

    private final Predicate<String> keyFilter;

    private final LazyBloomFilter lazyBloomFilter;

    CacheChangesTracker(Predicate<String> keyFilter, List<CacheChangesTracker> changeTrackers, int bloomFilterSize) {
        this.changeTrackers = changeTrackers;
        this.keyFilter = keyFilter;
        this.lazyBloomFilter = new LazyBloomFilter(bloomFilterSize);
        changeTrackers.add(this);
    }

    public void putDocument(String key) {
        if (keyFilter.apply(key)) {
            lazyBloomFilter.put(key);
        }
    }

    public void invalidateDocument(String key) {
        if (keyFilter.apply(key)) {
            lazyBloomFilter.put(key);
        }
    }

    public boolean mightBeenAffected(String key) {
        return keyFilter.apply(key) && lazyBloomFilter.mightContain(key);
    }

    @Override
    public void close() {
        changeTrackers.remove(this);

        if (LOG.isDebugEnabled()) {
            if (lazyBloomFilter.filter == null) {
                LOG.debug("Disposing CacheChangesTracker for {}, no filter was needed", keyFilter);
            } else {
                LOG.debug("Disposing CacheChangesTracker for {}, filter fpp was: {}", keyFilter, lazyBloomFilter.filter.expectedFpp());
            }
        }
    }

    public static class LazyBloomFilter {

        private static final double FPP = 0.01d;

        private final int entries;

        private volatile BloomFilter<String> filter;

        public LazyBloomFilter(int entries) {
            this.entries = entries;
        }

        public synchronized void put(String entry) {
            getFilter().put(entry);
        }

        public boolean mightContain(String entry) {
            if (filter == null) {
                return false;
            } else {
                synchronized (this) {
                    return filter.mightContain(entry);
                }
            }
        }

        private BloomFilter<String> getFilter() {
            if (filter == null) {
                filter = BloomFilter.create(new Funnel<String>() {
                    private static final long serialVersionUID = -7114267990225941161L;

                    @Override
                    public void funnel(String from, PrimitiveSink into) {
                        into.putUnencodedChars(from);
                    }
                }, entries, FPP);
            }
            return filter;
        }
    }
}
