Quick Start
It is the best to go over a few lines of sample code to become familiar with Krati.
You can obtain a Krati distribution of version 0.4.2 or above.
The src/examples directory from the distribution contains a number of sample files such as KratiDataCache.java and KratiDataStore.java.
The KratiDataStore.java below shows how to create a fixed-capacity key-value store using class SimpleDataStore.
The store capacity is 1.5*keyCount as defined in the createDataStore method. A segment factory
called MemorySegmentFactory is used for storing key-value pairs in main memory to provide the fastest read and write access.
You can override the createSegmentFactory to provide mmap-based MappedSegmentFactory or Java Nio channel-based
ChannelSegmentFactory.
package krati.examples;
import java.io.File;
import java.util.Random;
import krati.cds.impl.segment.SegmentFactory;
import krati.cds.impl.store.SimpleDataStore;
import krati.cds.store.DataStore;
/**
* A fixed-capacity key-value store.
*/
public class KratiDataStore
{
private final int _keyCount;
private final DataStore _store;
/**
* Constructs KratiDataStore.
*
* @param keyCount the number of keys.
* @param homeDir the home directory for storing data.
* @throws Exception if a DataStore instance can not be created.
*/
public KratiDataStore(int keyCount, File homeDir) throws Exception
{
_keyCount = keyCount;
_store = createDataStore(keyCount, homeDir);
}
/**
* @return the underlying data store.
*/
public final DataStore getDataStore()
{
return _store;
}
/**
* Creates a data store instance.
* Subclasses can override this method to provide specific DataStore implementations such as DynamicDataStore.
*/
protected DataStore createDataStore(int keyCount, File storeDir) throws Exception
{
int capacity = (int)(keyCount * 1.5);
return new SimpleDataStore(storeDir,
capacity, /* capacity */
10000, /* update batch size */
5, /* number of update batches required to sync indexes.dat */
128, /* segment file size in MB */
createSegmentFactory());
}
/**
* Creates a segment factory.
* Subclasses can override this method to provide a specific segment factory such as ChannelSegmentFactory and MappedSegmentFactory.
*
* @return the segment factory.
*/
protected SegmentFactory createSegmentFactory()
{
return new krati.cds.impl.segment.MemorySegmentFactory();
}
/**
* Creates data for a given key.
* Subclasses can override this method to provide specific values for a given key.
*/
protected byte[] createDataForKey(String key)
{
return ("Here is your data for " + key).getBytes();
}
/**
* Populates the underlying data store.
*
* @throws Exception
*/
public void populate() throws Exception
{
for(int i = 0; i < _keyCount; i++)
{
String str = "key." + i;
byte[] key = str.getBytes();
byte[] value = createDataForKey(str);
_store.put(key, value);
}
_store.sync();
}
/**
* Perform a number of random reads from the underlying data store.
*
* @param readCnt the number of reads
*/
public void doRandomReads(int readCnt)
{
Random rand = new Random();
for(int i = 0; i < readCnt; i++)
{
int keyId = rand.nextInt(_keyCount);
String str = "key." + keyId;
byte[] key = str.getBytes();
byte[] value = _store.get(key);
System.out.printf("Key=%s\tValue=%s%n", str, new String(value));
}
}
/**
* java -Xmx4G krati.examples.KratiDataStore keyCount homeDir
*
* @param args
*/
public static void main(String[] args)
{
try
{
// Parse arguments: keyCount homeDir
int keyCount = Integer.parseInt(args[0]);
File homeDir = new File(args[1]);
// Create an instance of Krati DataStore
File storeHomeDir = new File(homeDir, KratiDataStore.class.getSimpleName());
KratiDataStore store = new KratiDataStore(keyCount, storeHomeDir);
// Populate data store
store.populate();
// Perform some random reads from data store.
store.doRandomReads(10);
}
catch(Exception e)
{
e.printStackTrace();
}
}
}