/*
 * Copyright 2016-2018 Crown Copyright
 *
 * Licensed 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 uk.gov.gchq.gaffer.types;

import uk.gov.gchq.koryphe.serialisation.json.JsonSimpleClassName;

import java.util.HashMap;
import java.util.Map;

/**
 * {@code FreqMap} extends {@link HashMap} with String keys and Long values, adding an upsert operation.
 */
@JsonSimpleClassName
public class FreqMap extends HashMap<String, Long> {
    private static final long serialVersionUID = -851105369975081220L;

    public FreqMap(final Map<? extends String, ? extends Long> m) {
        super(m);
    }

    public FreqMap() {
    }

    public FreqMap(final int initialCapacity) {
        super(initialCapacity);
    }

    public FreqMap(final int initialCapacity, final float loadFactor) {
        super(initialCapacity, loadFactor);
    }

    /**
     * Adds a new key and value to the map if the key is not already there.
     * If the key is already there, the value supplied is added to the existing value for the key and the result is inserted into the map.
     *
     * @param key   The key in the map to increment or insert.
     * @param value The value to increment by or initialise to.
     */
    public void upsert(final String key, final Long value) {
        final Long currentValue = get(key);
        if (null == currentValue) {
            put(key, value);
        } else {
            put(key, currentValue + value);
        }
    }

    /**
     * Increments the value of an existing key by 1.
     * If the key doesn't exist, initialises the value to 1.
     *
     * @param key The key to increment or insert.
     */
    public void upsert(final String key) {
        upsert(key, 1L);
    }
}

@@ -632,16 +632,71 @@
 types;%0A%0A
+import jdk.nashorn.internal.runtime.regexp.joni.Regex;%0A
 import u
@@ -802,16 +802,159 @@
 til.Map;
+%0Aimport java.util.function.BiPredicate;%0Aimport java.util.function.Function;%0Aimport java.util.regex.Pattern;%0Aimport java.util.stream.Collectors;
 %0A%0A/**%0A *
@@ -2412,11 +2412,935 @@
 );%0A    %7D
+%0A%0A    /**%0A     * Creates a filtered copy of the map using a supplied regex pattern.%0A     *%0A     * @param regexPattern  A valid regex pattern as a string.%0A     * @return  A new frequency map with only the filtered entries present.%0A     */%0A    public FreqMap filterRegex(final String regexPattern) %7B%0A        return filterPredicate((s, l) -%3E s.matches(regexPattern));%0A    %7D%0A%0A    /**%0A     * Creates a filtered copy of the map using a supplied predicate.%0A     *%0A     * @param predicate  A valid predicate that can use one or both of the key-value pairings.%0A     * @return  A new frequency map with only the filtered entries present.%0A     */%0A    public FreqMap filterPredicate(BiPredicate%3CString, Long%3E predicate) %7B%0A        FreqMap f = new FreqMap();%0A%0A        this.entrySet().stream().filter(e -%3E predicate.test(e.getKey(), e.getValue()))%0A                .forEach(e -%3E f.upsert(e.getKey(), e.getValue()));%0A%0A        return f;%0A    %7D
 %0A%7D%0A

add filtering methods