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

com.epam.deltix.util.collections.TripleKeyMap Maven / Gradle / Ivy

The newest version!
/*
 * Copyright 2021 EPAM Systems, Inc
 *
 * See the NOTICE file distributed with this work for additional information
 * regarding copyright ownership. 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 com.epam.deltix.util.collections;

import java.util.EnumMap;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.Collections;

/**
 * Triple keys map.
 */
public class TripleKeyMap {
    @SuppressWarnings("unchecked")
    private static final InternalMapFactory SIMPLE_FACTORY = new ClassMapFactory(null, null, null);

    private final InternalMapFactory factory;
    private final Map>> map;

    public static  TripleKeyMap create() {
        return new TripleKeyMap();
    }

    public static  TripleKeyMap create(Class outerKeyClass,
                                                                     Class middleKeyClass,
                                                                     Class innerKeyClass) {
        return new TripleKeyMap(outerKeyClass, middleKeyClass, innerKeyClass);
    }

    @SuppressWarnings("unchecked")
    public TripleKeyMap() {
        this(SIMPLE_FACTORY);
    }

    public TripleKeyMap(Class outerKeyClass,
                        Class middleKeyClass,
                        Class innerKeyClass) {
        this(new ClassMapFactory(outerKeyClass, middleKeyClass, innerKeyClass));
    }

    public TripleKeyMap(InternalMapFactory factory) {
        this.factory = factory;
        map = factory.createOuterMap();
    }

    /////////////////////////// METHODS /////////////////////////

    public boolean isEmpty() {
        return map.isEmpty();
    }

    public int size() {
        return map.size();
    }

    public void clear() {
        map.clear();
    }

    public boolean containsKey(OK outerKey, MK middleKey, IK innerKey) {
        Map> middleMap = map.get(outerKey);
        if (middleMap != null) {
            Map innerMap = middleMap.get(middleKey);
            if (innerMap != null)
                return innerMap.containsKey(innerKey);
        }
        return false;
    }

    public V get(OK outerKey, MK middleKey, IK innerKey) {
        Map> middleMap = map.get(outerKey);
        if (middleMap != null) {
            Map innerMap = middleMap.get(middleKey);
            if (innerMap != null)
                return innerMap.get(innerKey);
        }
        return null;
    }

    public V put(OK outerKey, MK middleKey, IK innerKey, V value) {
        Map> middleMap = map.get(outerKey);
        if (middleMap == null) {
            middleMap = factory.createMiddleMap();
            map.put(outerKey, middleMap);
        }
        Map innerMap = middleMap.get(middleKey);
        if (innerMap == null) {
            innerMap = factory.createInnerMap();
            middleMap.put(middleKey, innerMap);
        }
        return innerMap.put(innerKey, value);
    }

    public V remove(OK outerKey, MK middleKey, IK innerKey) {
        V result = null;
        Map> middleMap = map.get(outerKey);
        if (middleMap != null) {
            Map innerMap = middleMap.get(middleKey);
            if (innerMap != null) {
                result = innerMap.remove(innerKey);

                if (innerMap.isEmpty())
                    middleMap.remove(middleKey);
            }
            if (middleMap.isEmpty())
                map.remove(outerKey);
        }
        return result;
    }

    public Set outerKeySet() {
        return map.keySet();
    }

    public Set middleKeySet(OK outerKey) {
        Map> middleMap = map.get(outerKey);
        return middleMap != null ? middleMap.keySet() : Collections.emptySet();
    }

    public Set innerKeySet(OK outerKey, MK middleKey) {
        Map> middleMap = map.get(outerKey);
        if (middleMap != null) {
            Map innerMap = middleMap.get(middleKey);
            return innerMap != null ? innerMap.keySet() : Collections.emptySet();
        }
        return Collections.emptySet();
    }

    ////////////////////////////// UTILITIES /////////////////////////

    @SuppressWarnings("unchecked")
    private static  Map create(Class keyClass) {
        if (keyClass == null)
            return new HashMap();

        if (keyClass.isEnum())
            return new EnumMap(keyClass);
        if (keyClass.isAssignableFrom(CharSequence.class))
            return new CharSequenceToObjectMap();
        return new HashMap();
    }

    ////////////////////////////// HELPER CLASSES /////////////////////////

    public static interface InternalMapFactory {
        Map>> createOuterMap();
        Map> createMiddleMap();
        Map createInnerMap();
    }

    public static class ClassMapFactory implements InternalMapFactory {
        private final Class outerKeyClass;
        private final Class middleKeyClass;
        private final Class innerKeyClass;

        public ClassMapFactory(Class outerKeyClass,
                               Class middleKeyClass,
                               Class innerKeyClass) {
            this.outerKeyClass = outerKeyClass;
            this.middleKeyClass = middleKeyClass;
            this.innerKeyClass = innerKeyClass;
        }

        @Override
        public Map>> createOuterMap() {
            return create(outerKeyClass);
        }

        @Override
        public Map> createMiddleMap() {
            return create(middleKeyClass);
        }

        @Override
        public Map createInnerMap() {
            return create(innerKeyClass);
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy