Project 3: Build a Single Server Key-Value Store

In project 3, you will implement a single-node key-value store.

Architecture Diagram

Figure: A single-node key-value store with three clients making simultaneous requests.

Summary

Multiple clients will be communicating with a single key-value server in a given messaging format (KVMessage) using a KVClient. Communication between the clients and the server will take place over the network through sockets (SocketServer and KVClientHandler). The KVServer uses a ThreadPool to support concurrent operations across multiple sets in a set-associative KVCache, which is backed by a KVStore.

Skeleton Code

The project skeleton you must build on top of is linked below. We recommend unpacking this download and dropping the directory in the github repository you used for projects 1 and 2. If you are using an IDE, be sure to separate your IDE-related files for each project such that nachos and kvstore are two independent projects. Do not modify the package statements; the code must be nested in edu.berkeley.cs162.

http://www-inst.eecs.berkeley.edu/~cs162/fa13/kvstore/proj3-skeleton.tar.gz

You can define additional classes and methods as you deem fit, but you must not modify the defined prototypes/interfaces. Be aware that you may need to implement methods that are not labeled with //implement me -- these comments are meant only as hints and are not comprehensive. Examples of how to create client and server instances to run the project are included in Client.java and Server.java.

Tasks (Weights)

  1. (20%) Implement the message parsing library in KVMessage. See specifications below.
  2. (10%) Implement the KVClient class that you are provided with, such that it will issue requests and handle responses (generated using KVMessage) using sockets.
  3. (20%) Implement a set-associative KVCache with the SecondChance eviction policy within each set. The cache should be instantiated with parameter(s) passed to the constructor.
  4. (15%) Implement dumpToFile and restoreFromFile in KVStore and toXML in KVCache.
  5. (10%) Implement a ThreadPool -- you are not allowed to use built-in threadpool libraries. The threadpool should accept different tasks and execute them asynchronously. The threadpool should maintain a queue of tasks submitted to it, and should assign free threads to tasks as soon as possible.
  6. (25%) Implement SocketServer, and KVClientHandler, and KVServer. You will need to use the threadpool to parallelize data storage into the dummy storage system provided to you (KVStore). Use the set-associative cache you implemented to make key lookups faster. You should follow a write-through caching policy. This task integrates the entire project and requires a general understanding of all other tasks.

Deliverables

  1. Tue 11/12: Initial design
  2. Thu 11/21: Code with JUnit tests
  3. Fri 11/22: Final design and group evaluation

You will have to submit JUnit test cases for each of the classes you will implement (KVMessage, KVClient, ThreadPool, KVStore, KVCache, and KVServer). The following are the expectations regarding testing:

Requirements

KVMessage Format

(Case-Sensitive) Error Messages

For network errors arising on the server when it is not possible to return the error to the client, you can drop this silently. For errors generated on the client (KVClient), you can drop this silently as well.

KVCache.toXML() Return Format

<?xml version="1.0" encoding="UTF-8"?>
<KVCache>
  <Set Id="id">
    <CacheEntry isReferenced="true/false" isValid="true/false">
      <Key>key</Key>
      <Value>value</Value>
    </CacheEntry>
  </Set>
</KVCache>

There should be as many Set elements as there are sets, and within each set, there should be as many CacheEntry elements as there are entries in each set. As mentioned earlier, the number of sets and the number of elements in each sets will be given in the constructor. Sets must have Integer ids starting from zero.

KVStore.dumpToFile(filename) Output Format

<?xml version="1.0" encoding="UTF-8"?>
<KVStore>
    <KVPair>
      <Key>key</Key>
      <Value>value</Value>
    </KVPair>
    <KVPair>
      <Key>key2</Key>
      <Value>value2</Value>
    </KVPair>
</KVStore>

On Testing

There are appropriate hooks to the autograder in the skeleton and a bareboned AutoGrader class has been provided to make it easier for you to write your own test cases. There will likely be an online autograder, but we are not promising one.

DO NOT remove AutoGrader hooks from the skeleton.