/*
// Licensed to Julian Hyde under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// Julian Hyde 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.olap4j.impl;

import java.util.Collections;
import java.util.Map;

/**
 * Unmodifiable map backed by an array.
 *
 * <p>Has the same benefits and limitations as {@link ArrayMap}. It is extremely
 * space-efficient but has poor performance for insert and lookup.
 *
 * <p>This structure is ideal if you are creating many maps with few elements.
 * The {@link #of(java.util.Map)} method will use
 * {@link java.util.Collections#emptyMap} and
 * {@link java.util.Collections#singletonMap(Object, Object)} if possible, and
 * these are even more space-efficient for maps of size 0 and 1.
 *
 * @author jhyde
 * @since Jan 16, 2010
 */
public class UnmodifiableArrayMap<K, V>
    extends ArrayMap<K, V>
{
    /**
     * Creates an UnmodifiableArrayMap.
     *
     * @param map Contents of map, copied on creation
     */
    public UnmodifiableArrayMap(Map<K, V> map) {
        super(map);
    }

    @Override
    public V put(K key, V value) {
        throw new UnsupportedOperationException();
    }

    @Override
    public V remove(Object key) {
        throw new UnsupportedOperationException();
    }

    @Override
    public void putAll(Map<? extends K, ? extends V> m) {
        throw new UnsupportedOperationException();
    }

    @Override
    public void clear() {
        throw new UnsupportedOperationException();
    }

    /**
     * Returns an unmodifiable array map with given contents.
     *
     * @param key First key
     * @param value First value
     * @param keyValues Second and sequent key/value pairs
     * @param <K> Key type
     * @param <V> Value type
     * @return Map with given contents
     */
    public static <K, V> Map<K, V> of(
        K key,
        V value,
        Object... keyValues)
    {
        if (keyValues.length == 0) {
            return Collections.singletonMap(key, value);
        }
        // Because UnmodifiableArrayMap is so bad at bulk inserts, it makes
        // sense to build another map just so we can populate the
        // UnmodifiableArrayMap in one shot. We require that the other map
        // preserves order; luckily mapOf uses LinkedHashMap.
        return new UnmodifiableArrayMap<K, V>(
            Olap4jUtil.mapOf(key, value, keyValues));
    }

    /**
     * Creates an unmodifable map as a shallow copy of a map.
     *
     * <p>Future changes to the map will not be reflected in the contents
     * of the map.
     *
     * @param <K> Key type
     * @param <V> Value type
     * @return Unmodifiable map with same contents that the map had at
     * call time
     */
    public static <K, V> Map<K, V> of(
        Map<K, V> map)
    {
        switch (map.size()) {
        case 0:
            return Collections.emptyMap();
        case 1:
            final Entry<K, V> entry = map.entrySet().iterator().next();
            return Collections.singletonMap(entry.getKey(), entry.getValue());
        default:
            //noinspection unchecked
            return new UnmodifiableArrayMap<K, V>(map);
        }
    }
}

// End UnmodifiableArrayMap.java
