/*
 * Copyright (C) 2011, Google Inc.
 * and other copyright owners as documented in the project's IP log.
 *
 * This program and the accompanying materials are made available
 * under the terms of the Eclipse Distribution License v1.0 which
 * accompanies this distribution, is reproduced below, and is
 * available at http://www.eclipse.org/org/documents/edl-v10.php
 *
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or
 * without modification, are permitted provided that the following
 * conditions are met:
 *
 * - Redistributions of source code must retain the above copyright
 *   notice, this list of conditions and the following disclaimer.
 *
 * - Redistributions in binary form must reproduce the above
 *   copyright notice, this list of conditions and the following
 *   disclaimer in the documentation and/or other materials provided
 *   with the distribution.
 *
 * - Neither the name of the Eclipse Foundation, Inc. nor the
 *   names of its contributors may be used to endorse or promote
 *   products derived from this software without specific prior
 *   written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
 * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

package org.eclipse.jgit.lib;

import java.util.Arrays;
import java.util.Iterator;
import java.util.NoSuchElementException;

/**
 * Fast, efficient map for {@link ObjectId} subclasses in only one map.
 * <p>
 * To use this map type, applications must have their entry value type extend
 * from {@link ObjectIdOwnerMap.Entry}, which itself extends from ObjectId.
 * <p>
 * Object instances may only be stored in <b>ONE</b> ObjectIdOwnerMap. This
 * restriction exists because the map stores internal map state within each
 * object instance. If an instance is be placed in another ObjectIdOwnerMap it
 * could corrupt one or both map's internal state.
 * <p>
 * If an object instance must be in more than one map, applications may use
 * ObjectIdOwnerMap for one of the maps, and {@link ObjectIdSubclassMap} for the
 * other map(s). It is encouraged to use ObjectIdOwnerMap for the map that is
 * accessed most often, as this implementation runs faster than the more general
 * ObjectIdSubclassMap implementation.
 *
 * @param <V>
 *            type of subclass of ObjectId that will be stored in the map.
 */
public class ObjectIdOwnerMap<V extends ObjectIdOwnerMap.Entry>
		implements Iterable<V>, ObjectIdSet {
	/** Size of the initial directory, will grow as necessary. */
	private static final int INITIAL_DIRECTORY = 1024;

	/** Number of bits in a segment's index. Segments are 2^11 in size. */
	private static final int SEGMENT_BITS = 11;

	private static final int SEGMENT_SHIFT = 32 - SEGMENT_BITS;

	/**
	 * Top level directory of the segments.
	 * <p>
	 * The low {@link #bits} of the SHA-1 are used to select the segment from
	 * this directory. Each segment is constant sized at 2^SEGMENT_BITS.
	 */
	V[][] directory;

	/** Total number of objects in this map. */
	int size;

	/** The map doubles in capacity when {@link #size} reaches this target. */
	private int grow;

	/** Number of low bits used to form the index into {@link #directory}. */
	int bits;

	/** Low bit mask to index into {@link #directory}, {@code 2^bits-1}. */
	private int mask;

	/** Create an empty map. */
	@SuppressWarnings("unchecked")
	public ObjectIdOwnerMap() {
		bits = 0;
		mask = 0;
		grow = computeGrowAt(bits);

		directory = (V[][]) new Entry[INITIAL_DIRECTORY][];
		directory[0] = newSegment();
	}

	/** Remove all entries from this map. */
	public void clear() {
		size = 0;

		for (V[] tbl : directory) {
			if (tbl == null)
				break;
			Arrays.fill(tbl, null);
		}
	}

	/**
	 * Lookup an existing mapping.
	 *
	 * @param toFind
	 *            the object identifier to find.
	 * @return the instance mapped to toFind, or null if no mapping exists.
	 */
	@SuppressWarnings("unchecked")
	public V get(final AnyObjectId toFind) {
		int h = toFind.w1;
		V obj = directory[h & mask][h >>> SEGMENT_SHIFT];
		for (; obj != null; obj = (V) obj.next)
			if (equals(obj, toFind))
				return obj;
		return null;
	}

	/**
	 * Returns true if this map contains the specified object.
	 *
	 * @param toFind
	 *            object to find.
	 * @return true if the mapping exists for this object; false otherwise.
	 */
	@Override
	public boolean contains(final AnyObjectId toFind) {
		return get(toFind) != null;
	}

	/**
	 * Store an object for future lookup.
	 * <p>
	 * An existing mapping for <b>must not</b> be in this map. Callers must
	 * first call {@link #get(AnyObjectId)} to verify there is no current
	 * mapping prior to adding a new mapping, or use {@link #addIfAbsent(Entry)}.
	 *
	 * @param newValue
	 *            the object to store.
	 * @param <Q>
	 *            type of instance to store.
	 */
	public <Q extends V> void add(final Q newValue) {
		if (++size == grow)
			grow();

		int h = newValue.w1;
		V[] table = directory[h & mask];
		h >>>= SEGMENT_SHIFT;

		newValue.next = table[h];
		table[h] = newValue;
	}

	/**
	 * Store an object for future lookup.
	 * <p>
	 * Stores {@code newValue}, but only if there is not already an object for
	 * the same object name. Callers can tell if the value is new by checking
	 * the return value with reference equality:
	 *
	 * <pre>
	 * V obj = ...;
	 * boolean wasNew = map.addIfAbsent(obj) == obj;
	 * </pre>
	 *
	 * @param newValue
	 *            the object to store.
	 * @return {@code newValue} if stored, or the prior value already stored and
	 *         that would have been returned had the caller used
	 *         {@code get(newValue)} first.
	 * @param <Q>
	 *            type of instance to store.
	 */
	@SuppressWarnings("unchecked")
	public <Q extends V> V addIfAbsent(final Q newValue) {
		int h = newValue.w1;
		V[] table = directory[h & mask];
		h >>>= SEGMENT_SHIFT;

		for (V obj = table[h]; obj != null; obj = (V) obj.next)
			if (equals(obj, newValue))
				return obj;

		newValue.next = table[h];
		table[h] = newValue;

		if (++size == grow)
			grow();
		return newValue;
	}

	/** @return number of objects in this map. */
	public int size() {
		return size;
	}

	/** @return true if {@link #size()} is 0. */
	public boolean isEmpty() {
		return size == 0;
	}

	@Override
	public Iterator<V> iterator() {
		return new Iterator<V>() {
			private int found;
			private int dirIdx;
			private int tblIdx;
			private V next;

			@Override
			public boolean hasNext() {
				return found < size;
			}

			@Override
			public V next() {
				if (next != null)
					return found(next);

				for (;;) {
					V[] table = directory[dirIdx];
					if (tblIdx == table.length) {
						if (++dirIdx >= (1 << bits))
							throw new NoSuchElementException();
						table = directory[dirIdx];
						tblIdx = 0;
					}

					while (tblIdx < table.length) {
						V v = table[tblIdx++];
						if (v != null)
							return found(v);
					}
				}
			}

			@SuppressWarnings("unchecked")
			private V found(V v) {
				found++;
				next = (V) v.next;
				return v;
			}

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

	@SuppressWarnings("unchecked")
	private void grow() {
		final int oldDirLen = 1 << bits;
		final int s = 1 << bits;

		bits++;
		mask = (1 << bits) - 1;
		grow = computeGrowAt(bits);

		// Quadruple the directory if it needs to expand. Expanding the
		// directory is expensive because it generates garbage, so try
		// to avoid doing it often.
		//
		final int newDirLen = 1 << bits;
		if (directory.length < newDirLen) {
			V[][] newDir = (V[][]) new Entry[newDirLen << 1][];
			System.arraycopy(directory, 0, newDir, 0, oldDirLen);
			directory = newDir;
		}

		// For every bucket of every old segment, split the chain between
		// the old segment and the new segment's corresponding bucket. To
		// select between them use the lowest bit that was just added into
		// the mask above. This causes the table to double in capacity.
		//
		for (int dirIdx = 0; dirIdx < oldDirLen; dirIdx++) {
			final V[] oldTable = directory[dirIdx];
			final V[] newTable = newSegment();

			for (int i = 0; i < oldTable.length; i++) {
				V chain0 = null;
				V chain1 = null;
				V next;

				for (V obj = oldTable[i]; obj != null; obj = next) {
					next = (V) obj.next;

					if ((obj.w1 & s) == 0) {
						obj.next = chain0;
						chain0 = obj;
					} else {
						obj.next = chain1;
						chain1 = obj;
					}
				}

				oldTable[i] = chain0;
				newTable[i] = chain1;
			}

			directory[oldDirLen + dirIdx] = newTable;
		}
	}

	@SuppressWarnings("unchecked")
	private final V[] newSegment() {
		return (V[]) new Entry[1 << SEGMENT_BITS];
	}

	private static final int computeGrowAt(int bits) {
		return 1 << (bits + SEGMENT_BITS);
	}

	private static final boolean equals(AnyObjectId firstObjectId,
			AnyObjectId secondObjectId) {
		return firstObjectId.w2 == secondObjectId.w2
				&& firstObjectId.w3 == secondObjectId.w3
				&& firstObjectId.w4 == secondObjectId.w4
				&& firstObjectId.w5 == secondObjectId.w5
				&& firstObjectId.w1 == secondObjectId.w1;
	}

	/** Type of entry stored in the {@link ObjectIdOwnerMap}. */
	public static abstract class Entry extends ObjectId {
		transient Entry next;

		/**
		 * Initialize this entry with a specific ObjectId.
		 *
		 * @param id
		 *            the id the entry represents.
		 */
		public Entry(AnyObjectId id) {
			super(id);
		}
	}
}
