/*
* An implementation of a Cache.
* First version -
* manage lines read from RandomAccessFile, which have key - values.
* Next changes:
* 1. Convert to Generics.
* 2. Use an interface instead ofRandomAccessFile.
*/
package prepare4interview.CacheTest;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.util.HashMap;
import java.util.LinkedList;
/**
*
* @author shay
*/
public class MyCache
{
/**************************************************************/
/* Constants: */
/**************************************************************/
public static final int DEF_CACHE_SIZE = 6;
/**************************************************************/
/* Members: */
/**************************************************************/
// Cache size:
int size;
// The Cache's storage"
HashMap
<String, String
> cache
;
// Defines the queue of values handled by the cache:
LinkedList<String> accessList;
/**************************************************************/
/* Constructors: */
/**************************************************************/
/**
* Base Constructor - all parameters:
* @param inpFile
* @param size
*/
{
this.inpFile = inpFile;
this.size = size;
this.cache = new HashMap<>(this.size);
this.accessList = new LinkedList<>();
}
/**
* OPtional Constructor - only Input File name:
* @param inpFile
*/
{
this(inpFile, MyCache.DEF_CACHE_SIZE);
}
/**************************************************************/
/* Class methods: */
/**************************************************************/
/**
* Get a value for the input key:
* @param keyStr
* @return
*/
{
if (keyStr == null)
return(null);
// in Cache?
int elemNr = this.accessList.size();
if (elemNr > 0 && (valStr = this.cache.get(keyStr)) != null)
{
System.
out.
println("key: " + keyStr
+ " Found value in cache: " + valStr
);
// Reloacte the key at the top of the Cache's Access list:
int keyIdx = this.accessList.indexOf(keyStr);
if (keyIdx > 1)
{
this.accessList.remove(keyIdx);
this.accessList.addFirst(keyStr);
System.
out.
println("key: " + keyStr
+ " Moved key to top from: " + keyIdx
);
}
return(valStr);
}
// Not found - read it from file:
try {
valStr = getValueFromSrc(keyStr);
} catch (MyCacheException ex) {
System.
err.
println("Search for key: " + keyStr
+ " failed; exception: " + ex.
getMessage());
return(null);
}
// If key not in cache and the cache is full -
// remove the least recently accessed:
if (elemNr == this.size)
{
String firstKey
= this.
accessList.
removeFirst();
this.cache.remove(firstKey);
}
// Add the missing key/value to the cache:
this.cache.put(keyStr, valStr);
this.accessList.addLast(keyStr);
System.
out.
println("key: " + keyStr
+ " Added value to cache: " + valStr
);
return(valStr);
}
/**************************************************************/
/* Class Methods, which might be moved to the interface */
/**************************************************************/
/**
* Search for the input key in the file and return its value
*
* @param keyStr
* @return
* @throws prepare4interview.CacheTest.MyCacheException
*/
public String getValueFromSrc
(String keyStr
) throws MyCacheException
{
String keyStrLc
= keyStr.
toLowerCase();
try
{
inpFile.seek(0L);
// Scan for the input string - which is the first field
// in the input line:
while ((inpLine = inpFile.readLine()) != null)
{
if (inpLine.toLowerCase().startsWith(keyStrLc))
{
valStr = inpLine;
System.
out.
println("getValueFromSrc() - Found value for the key:" + valStr
);
break;
}
}
throw new MyCacheException("getValueFromSrc()", ex);
}
return(valStr);
}
/***************************************************************/
/**
*
* @param args
*/
public static void main
(String[] args
)
{
if (args.length == 0)
{
System.
err.
println("Usage:" + MyCache.
class.
getName() + " <inpFileName>");
}
System.
out.
println("Starting");
try {
System.
err.
println("Error: input file name: " + inpFileName
+ " does not exist!");
}
MyCache myCache = new MyCache(inpFile);
valStr = myCache.getValue("bbbb");
valStr = myCache.getValue("2222");
valStr = myCache.getValue("aaa");
valStr = myCache.getValue("bbbb");
valStr = myCache.getValue("GGGGG");
valStr = myCache.getValue("aaa");
valStr = myCache.getValue("2222");
valStr = myCache.getValue("ccccc");
valStr = myCache.getValue("eeeee");
}
}