// Path: src/com/nobigsoftware/util/BuilderCache.java
// public interface BuilderCache
// {
//     /**
//      * Get a cached item.
//      * 
//      * @param key  The key used to identify the item.  The key uniquely identifies all
//      *  of the source information that will go into building the item if this call fails
//      *  to retrieve a cached version.  Typically this will be a cryptographic hash of
//      *  the serialized form of that information.
//      * 
//      * @return  the item that was previously cached under the key, or null if no such item
//      *  can be retrieved.
//      */
//     Serializable getCachedItem(String key);
//     
//     /**
//      * This method may be called when an item is built, providing an opportunity to
//      * cache it.
//      * 
//      * @param key   The key that will be used to identify the item in future calls to {@link #getCachedItem(String)}.
//      *      Only letters, digits, and underscores are valid in keys, and key length is limited to 32 characters.
//      *      The behaviour of this method for invalid keys is undefined.
//      *      <P>
//      *      Keys that differ only by case may or may not be considered equal by this class.
//      * @param item  The item to cache, if desired
//      */
//     void maybeCacheItem(String key, Serializable item);
// }


import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.Map;
import org.junit.Assert;
import org.junit.Test;
import com.nobigsoftware.util.BuilderCache;

package com.nobigsoftware.dfalex;




public class BuilderCacheTest extends TestBase
{
    @Test
    public void test() throws Exception
    {
        InMemoryBuilderCache cache = new InMemoryBuilderCache();

        DfaBuilder<JavaToken> builder = new DfaBuilder<>(cache);
        _build(builder);
        Assert.assertEquals(1, cache.m_cache.size());
        Assert.assertEquals(0, cache.m_hits);
        
        builder.clear();
        _build(builder);
        Assert.assertEquals(1, cache.m_cache.size());
        Assert.assertEquals(1, cache.m_hits);

        builder = new DfaBuilder<>(cache);
        _build(builder);
        Assert.assertEquals(1, cache.m_cache.size());
        Assert.assertEquals(2, cache.m_hits);
    }
    
    private void _build(DfaBuilder<JavaToken> builder) throws Exception
    {
        for (JavaToken tok : JavaToken.values())
        {
            builder.addPattern(tok.m_pattern, tok);
        }
        EnumSet<JavaToken> lang = EnumSet.allOf(JavaToken.class);
        DfaState<?> start = builder.build(lang, null);
        _checkDfa(start, "JavaTest.out.txt", false);
    }
    

// Path: src/com/nobigsoftware/util/BuilderCache.java
// public interface BuilderCache
// {
//     /**
//      * Get a cached item.
//      * 
//      * @param key  The key used to identify the item.  The key uniquely identifies all
//      *  of the source information that will go into building the item if this call fails
//      *  to retrieve a cached version.  Typically this will be a cryptographic hash of
//      *  the serialized form of that information.
//      * 
//      * @return  the item that was previously cached under the key, or null if no such item
//      *  can be retrieved.
//      */
//     Serializable getCachedItem(String key);
//     
//     /**
//      * This method may be called when an item is built, providing an opportunity to
//      * cache it.
//      * 
//      * @param key   The key that will be used to identify the item in future calls to {@link #getCachedItem(String)}.
//      *      Only letters, digits, and underscores are valid in keys, and key length is limited to 32 characters.
//      *      The behaviour of this method for invalid keys is undefined.
//      *      <P>
//      *      Keys that differ only by case may or may not be considered equal by this class.
//      * @param item  The item to cache, if desired
//      */
//     void maybeCacheItem(String key, Serializable item);
// }


// Path: test/com/nobigsoftware/dfalex/BuilderCacheTest.java
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.Map;
import org.junit.Assert;
import org.junit.Test;
import com.nobigsoftware.util.BuilderCache;

package com.nobigsoftware.dfalex;




public class BuilderCacheTest extends TestBase
{
    @Test
    public void test() throws Exception
    {
        InMemoryBuilderCache cache = new InMemoryBuilderCache();

        DfaBuilder<JavaToken> builder = new DfaBuilder<>(cache);
        _build(builder);
        Assert.assertEquals(1, cache.m_cache.size());
        Assert.assertEquals(0, cache.m_hits);
        
        builder.clear();
        _build(builder);
        Assert.assertEquals(1, cache.m_cache.size());
        Assert.assertEquals(1, cache.m_hits);

        builder = new DfaBuilder<>(cache);
        _build(builder);
        Assert.assertEquals(1, cache.m_cache.size());
        Assert.assertEquals(2, cache.m_hits);
    }
    
    private void _build(DfaBuilder<JavaToken> builder) throws Exception
    {
        for (JavaToken tok : JavaToken.values())
        {
            builder.addPattern(tok.m_pattern, tok);
        }
        EnumSet<JavaToken> lang = EnumSet.allOf(JavaToken.class);
        DfaState<?> start = builder.build(lang, null);
        _checkDfa(start, "JavaTest.out.txt", false);
    }
    

    private static class InMemoryBuilderCache implements BuilderCache
