// Path: src/main/java/edu/berkeley/nlp/lm/ContextEncodedNgramLanguageModel.java
// public static class LmContextInfo
// {
// 
// 	/**
// 	 * Offset of context (prefix) of an n-gram
// 	 */
// 	public long offset = -1L;
// 
// 	/**
// 	 * The (0-based) length of <code>context</code> (i.e.
// 	 * <code>order == 0</code> iff <code>context</code> refers to a
// 	 * unigram).
// 	 * 
// 	 * Use -1 for an empty context.
// 	 */
// 	public int order = -1;
// 
// }


import java.util.Arrays;
import java.util.concurrent.atomic.AtomicIntegerArray;
import edu.berkeley.nlp.lm.ContextEncodedNgramLanguageModel.LmContextInfo;
import edu.berkeley.nlp.lm.util.Annotations.OutputParameter;
	public ContextEncodedDirectMappedLmCache(final int cacheBits, final boolean threadSafe) {
		cacheSize = (1 << cacheBits) - 1;
		this.threadSafe = threadSafe;
		if (threadSafe) {
			threadUnsafeArray = null;
			threadSafeArray = new ThreadLocal<long[]>()
			{
				@Override
				protected long[] initialValue() {
					return allocCache();
				}

			};
		} else {
			threadSafeArray = null;
			threadUnsafeArray = allocCache();
		}

	}

	/**
	 * @return
	 */
	private long[] allocCache() {
		final long[] array = new long[STRUCT_LENGTH * cacheSize];
		Arrays.fill(array, -1);
		return array;
	}

	@Override
// Path: src/main/java/edu/berkeley/nlp/lm/ContextEncodedNgramLanguageModel.java
// public static class LmContextInfo
// {
// 
// 	/**
// 	 * Offset of context (prefix) of an n-gram
// 	 */
// 	public long offset = -1L;
// 
// 	/**
// 	 * The (0-based) length of <code>context</code> (i.e.
// 	 * <code>order == 0</code> iff <code>context</code> refers to a
// 	 * unigram).
// 	 * 
// 	 * Use -1 for an empty context.
// 	 */
// 	public int order = -1;
// 
// }


// Path: src/main/java/edu/berkeley/nlp/lm/cache/ContextEncodedDirectMappedLmCache.java
import java.util.Arrays;
import java.util.concurrent.atomic.AtomicIntegerArray;
import edu.berkeley.nlp.lm.ContextEncodedNgramLanguageModel.LmContextInfo;
import edu.berkeley.nlp.lm.util.Annotations.OutputParameter;

	public ContextEncodedDirectMappedLmCache(final int cacheBits, final boolean threadSafe) {
		cacheSize = (1 << cacheBits) - 1;
		this.threadSafe = threadSafe;
		if (threadSafe) {
			threadUnsafeArray = null;
			threadSafeArray = new ThreadLocal<long[]>()
			{
				@Override
				protected long[] initialValue() {
					return allocCache();
				}

			};
		} else {
			threadSafeArray = null;
			threadUnsafeArray = allocCache();
		}

	}

	/**
	 * @return
	 */
	private long[] allocCache() {
		final long[] array = new long[STRUCT_LENGTH * cacheSize];
		Arrays.fill(array, -1);
		return array;
	}

	@Override
	public float getCached(final long contextOffset, final int contextOrder, final int word, final int hash, @OutputParameter final LmContextInfo outputPrefix) {