/*
 * 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.internal.storage.dfs;


/**
 * Caches recently used objects for {@link DfsReader}.
 * <p>
 * This cache is not thread-safe. Each reader should have its own cache.
 */
final class DeltaBaseCache {
	private static final int TABLE_BITS = 10;

	private static final int MASK_BITS = 32 - TABLE_BITS;

	private static int hash(long position) {
		return (((int) position) << MASK_BITS) >>> MASK_BITS;
	}

	private int maxByteCount;
	private int curByteCount;

	private final Entry[] table;

	private Entry lruHead;
	private Entry lruTail;

	DeltaBaseCache(DfsReader reader) {
		this(reader.getOptions().getDeltaBaseCacheLimit());
	}

	DeltaBaseCache(int maxBytes) {
		maxByteCount = maxBytes;
		table = new Entry[1 << TABLE_BITS];
	}

	Entry get(DfsPackKey key, long position) {
		Entry e = table[hash(position)];
		for (; e != null; e = e.tableNext) {
			if (e.offset == position && key.equals(e.pack)) {
				moveToHead(e);
				return e;
			}
		}
		return null;
	}

	void put(DfsPackKey key, long offset, int objectType, byte[] data) {
		if (data.length > maxByteCount)
			return; // Too large to cache.

		curByteCount += data.length;
		releaseMemory();

		int tableIdx = hash(offset);
		Entry e = new Entry(key, offset, objectType, data);
		e.tableNext = table[tableIdx];
		table[tableIdx] = e;
		lruPushHead(e);
	}

	private void releaseMemory() {
		while (curByteCount > maxByteCount && lruTail != null) {
			Entry e = lruTail;
			curByteCount -= e.data.length;
			lruRemove(e);
			removeFromTable(e);
		}
	}

	private void removeFromTable(Entry e) {
		int tableIdx = hash(e.offset);
		Entry p = table[tableIdx];

		if (p == e) {
			table[tableIdx] = e.tableNext;
			return;
		}

		for (; p != null; p = p.tableNext) {
			if (p.tableNext == e) {
				p.tableNext = e.tableNext;
				return;
			}
		}

		throw new IllegalStateException(String.format(
				"entry for %s:%d not in table", //$NON-NLS-1$
				e.pack, Long.valueOf(e.offset)));
	}

	private void moveToHead(Entry e) {
		if (e != lruHead) {
			lruRemove(e);
			lruPushHead(e);
		}
	}

	private void lruRemove(Entry e) {
		Entry p = e.lruPrev;
		Entry n = e.lruNext;

		if (p != null) {
			p.lruNext = n;
		} else {
			lruHead = n;
		}

		if (n != null) {
			n.lruPrev = p;
		} else {
			lruTail = p;
		}
	}

	private void lruPushHead(Entry e) {
		Entry n = lruHead;
		e.lruNext = n;
		if (n != null)
			n.lruPrev = e;
		else
			lruTail = e;

		e.lruPrev = null;
		lruHead = e;
	}

	int getMemoryUsed() {
		return curByteCount;
	}

	int getMemoryUsedByLruChainForTest() {
		int r = 0;
		for (Entry e = lruHead; e != null; e = e.lruNext) {
			r += e.data.length;
		}
		return r;
	}

	int getMemoryUsedByTableForTest() {
		int r = 0;
		for (int i = 0; i < table.length; i++) {
			for (Entry e = table[i]; e != null; e = e.tableNext) {
				r += e.data.length;
			}
		}
		return r;
	}

	static class Entry {
		final DfsPackKey pack;
		final long offset;
		final int type;
		final byte[] data;

		Entry tableNext;
		Entry lruPrev;
		Entry lruNext;

		Entry(DfsPackKey key, long offset, int type, byte[] data) {
			this.pack = key;
			this.offset = offset;
			this.type = type;
			this.data = data;
		}
	}
}
