Adjust checkstyle rules. Make checkstyle fail the build when violations are found. Correct all current checkstyle violations.

This commit is contained in:
Ilkka Seppala
2015-12-25 23:49:28 +02:00
parent 9fbb085985
commit cec9a99410
167 changed files with 1242 additions and 969 deletions

View File

@ -21,7 +21,7 @@ package com.iluwatar.caching;
* application data. The cache itself is implemented as an internal (Java) data structure. It adopts
* a Least-Recently-Used (LRU) strategy for evicting data from itself when its full. The three
* strategies are individually tested. The testing of the cache is restricted towards saving and
* querying of user accounts from the underlying data store ( {@link DBManager}). The main class (
* querying of user accounts from the underlying data store ( {@link DbManager}). The main class (
* {@link App} is not aware of the underlying mechanics of the application (i.e. save and query) and
* whether the data is coming from the cache or the DB (i.e. separation of concern). The AppManager
* ({@link AppManager}) handles the transaction of data to-and-from the underlying data store
@ -43,7 +43,7 @@ public class App {
* @param args command line args
*/
public static void main(String[] args) {
AppManager.initDB(false); // VirtualDB (instead of MongoDB) was used in running the JUnit tests
AppManager.initDb(false); // VirtualDB (instead of MongoDB) was used in running the JUnit tests
// and the App class to avoid Maven compilation errors. Set flag to
// true to run the tests with MongoDB (provided that MongoDB is
// installed and socket connection is open).

View File

@ -21,18 +21,21 @@ public class AppManager {
* data storage or a simple Java data structure to (temporarily) store the data/objects during
* runtime.
*/
public static void initDB(boolean useMongoDB) {
if (useMongoDB) {
public static void initDb(boolean useMongoDb) {
if (useMongoDb) {
try {
DBManager.connect();
DbManager.connect();
} catch (ParseException e) {
e.printStackTrace();
}
} else {
DBManager.createVirtualDB();
DbManager.createVirtualDb();
}
}
/**
* Initialize caching policy
*/
public static void initCachingPolicy(CachingPolicy policy) {
cachingPolicy = policy;
if (cachingPolicy == CachingPolicy.BEHIND) {
@ -50,15 +53,21 @@ public class AppManager {
CacheStore.initCapacity(capacity);
}
public static UserAccount find(String userID) {
/**
* Find user account
*/
public static UserAccount find(String userId) {
if (cachingPolicy == CachingPolicy.THROUGH || cachingPolicy == CachingPolicy.AROUND) {
return CacheStore.readThrough(userID);
return CacheStore.readThrough(userId);
} else if (cachingPolicy == CachingPolicy.BEHIND) {
return CacheStore.readThroughWithWriteBackPolicy(userID);
return CacheStore.readThroughWithWriteBackPolicy(userId);
}
return null;
}
/**
* Save user account
*/
public static void save(UserAccount userAccount) {
if (cachingPolicy == CachingPolicy.THROUGH) {
CacheStore.writeThrough(userAccount);

View File

@ -9,73 +9,96 @@ import java.util.ArrayList;
*/
public class CacheStore {
static LRUCache cache = null;
static LruCache cache = null;
/**
* Init cache capacity
*/
public static void initCapacity(int capacity) {
if (null == cache)
cache = new LRUCache(capacity);
else
if (null == cache) {
cache = new LruCache(capacity);
} else {
cache.setCapacity(capacity);
}
}
public static UserAccount readThrough(String userID) {
if (cache.contains(userID)) {
/**
* Get user account using read-through cache
*/
public static UserAccount readThrough(String userId) {
if (cache.contains(userId)) {
System.out.println("# Cache Hit!");
return cache.get(userID);
return cache.get(userId);
}
System.out.println("# Cache Miss!");
UserAccount userAccount = DBManager.readFromDB(userID);
cache.set(userID, userAccount);
UserAccount userAccount = DbManager.readFromDb(userId);
cache.set(userId, userAccount);
return userAccount;
}
/**
* Get user account using write-through cache
*/
public static void writeThrough(UserAccount userAccount) {
if (cache.contains(userAccount.getUserID())) {
DBManager.updateDB(userAccount);
if (cache.contains(userAccount.getUserId())) {
DbManager.updateDb(userAccount);
} else {
DBManager.writeToDB(userAccount);
DbManager.writeToDb(userAccount);
}
cache.set(userAccount.getUserID(), userAccount);
cache.set(userAccount.getUserId(), userAccount);
}
/**
* Get user account using write-around cache
*/
public static void writeAround(UserAccount userAccount) {
if (cache.contains(userAccount.getUserID())) {
DBManager.updateDB(userAccount);
cache.invalidate(userAccount.getUserID()); // Cache data has been updated -- remove older
if (cache.contains(userAccount.getUserId())) {
DbManager.updateDb(userAccount);
cache.invalidate(userAccount.getUserId()); // Cache data has been updated -- remove older
// version from cache.
} else {
DBManager.writeToDB(userAccount);
DbManager.writeToDb(userAccount);
}
}
public static UserAccount readThroughWithWriteBackPolicy(String userID) {
if (cache.contains(userID)) {
/**
* Get user account using read-through cache with write-back policy
*/
public static UserAccount readThroughWithWriteBackPolicy(String userId) {
if (cache.contains(userId)) {
System.out.println("# Cache Hit!");
return cache.get(userID);
return cache.get(userId);
}
System.out.println("# Cache Miss!");
UserAccount userAccount = DBManager.readFromDB(userID);
UserAccount userAccount = DbManager.readFromDb(userId);
if (cache.isFull()) {
System.out.println("# Cache is FULL! Writing LRU data to DB...");
UserAccount toBeWrittenToDB = cache.getLRUData();
DBManager.upsertDB(toBeWrittenToDB);
UserAccount toBeWrittenToDb = cache.getLruData();
DbManager.upsertDb(toBeWrittenToDb);
}
cache.set(userID, userAccount);
cache.set(userId, userAccount);
return userAccount;
}
/**
* Set user account
*/
public static void writeBehind(UserAccount userAccount) {
if (cache.isFull() && !cache.contains(userAccount.getUserID())) {
if (cache.isFull() && !cache.contains(userAccount.getUserId())) {
System.out.println("# Cache is FULL! Writing LRU data to DB...");
UserAccount toBeWrittenToDB = cache.getLRUData();
DBManager.upsertDB(toBeWrittenToDB);
UserAccount toBeWrittenToDb = cache.getLruData();
DbManager.upsertDb(toBeWrittenToDb);
}
cache.set(userAccount.getUserID(), userAccount);
cache.set(userAccount.getUserId(), userAccount);
}
/**
* Clears cache
*/
public static void clearCache() {
if (null != cache)
if (null != cache) {
cache.clear();
}
}
/**
@ -83,14 +106,18 @@ public class CacheStore {
*/
public static void flushCache() {
System.out.println("# flushCache...");
if (null == cache)
if (null == cache) {
return;
}
ArrayList<UserAccount> listOfUserAccounts = cache.getCacheDataInListForm();
for (UserAccount userAccount : listOfUserAccounts) {
DBManager.upsertDB(userAccount);
DbManager.upsertDb(userAccount);
}
}
/**
* Print user accounts
*/
public static String print() {
ArrayList<UserAccount> listOfUserAccounts = cache.getCacheDataInListForm();
StringBuilder sb = new StringBuilder();

View File

@ -21,7 +21,7 @@ import com.mongodb.client.model.UpdateOptions;
* during runtime (createVirtualDB()).</p>
*
*/
public class DBManager {
public class DbManager {
private static MongoClient mongoClient;
private static MongoDatabase db;
@ -29,21 +29,31 @@ public class DBManager {
private static HashMap<String, UserAccount> virtualDB;
public static void createVirtualDB() {
/**
* Create DB
*/
public static void createVirtualDb() {
useMongoDB = false;
virtualDB = new HashMap<String, UserAccount>();
}
/**
* Connect to DB
*/
public static void connect() throws ParseException {
useMongoDB = true;
mongoClient = new MongoClient();
db = mongoClient.getDatabase("test");
}
public static UserAccount readFromDB(String userID) {
/**
* Read user account from DB
*/
public static UserAccount readFromDb(String userId) {
if (!useMongoDB) {
if (virtualDB.containsKey(userID))
return virtualDB.get(userID);
if (virtualDB.containsKey(userId)) {
return virtualDB.get(userId);
}
return null;
}
if (null == db) {
@ -54,18 +64,22 @@ public class DBManager {
}
}
FindIterable<Document> iterable =
db.getCollection("user_accounts").find(new Document("userID", userID));
if (iterable == null)
db.getCollection("user_accounts").find(new Document("userID", userId));
if (iterable == null) {
return null;
}
Document doc = iterable.first();
UserAccount userAccount =
new UserAccount(userID, doc.getString("userName"), doc.getString("additionalInfo"));
new UserAccount(userId, doc.getString("userName"), doc.getString("additionalInfo"));
return userAccount;
}
public static void writeToDB(UserAccount userAccount) {
/**
* Write user account to DB
*/
public static void writeToDb(UserAccount userAccount) {
if (!useMongoDB) {
virtualDB.put(userAccount.getUserID(), userAccount);
virtualDB.put(userAccount.getUserId(), userAccount);
return;
}
if (null == db) {
@ -76,13 +90,16 @@ public class DBManager {
}
}
db.getCollection("user_accounts").insertOne(
new Document("userID", userAccount.getUserID()).append("userName",
new Document("userID", userAccount.getUserId()).append("userName",
userAccount.getUserName()).append("additionalInfo", userAccount.getAdditionalInfo()));
}
public static void updateDB(UserAccount userAccount) {
/**
* Update DB
*/
public static void updateDb(UserAccount userAccount) {
if (!useMongoDB) {
virtualDB.put(userAccount.getUserID(), userAccount);
virtualDB.put(userAccount.getUserId(), userAccount);
return;
}
if (null == db) {
@ -93,7 +110,7 @@ public class DBManager {
}
}
db.getCollection("user_accounts").updateOne(
new Document("userID", userAccount.getUserID()),
new Document("userID", userAccount.getUserId()),
new Document("$set", new Document("userName", userAccount.getUserName()).append(
"additionalInfo", userAccount.getAdditionalInfo())));
}
@ -102,9 +119,9 @@ public class DBManager {
*
* Insert data into DB if it does not exist. Else, update it.
*/
public static void upsertDB(UserAccount userAccount) {
public static void upsertDb(UserAccount userAccount) {
if (!useMongoDB) {
virtualDB.put(userAccount.getUserID(), userAccount);
virtualDB.put(userAccount.getUserId(), userAccount);
return;
}
if (null == db) {
@ -115,8 +132,8 @@ public class DBManager {
}
}
db.getCollection("user_accounts").updateOne(
new Document("userID", userAccount.getUserID()),
new Document("$set", new Document("userID", userAccount.getUserID()).append("userName",
new Document("userID", userAccount.getUserId()),
new Document("$set", new Document("userID", userAccount.getUserId()).append("userName",
userAccount.getUserName()).append("additionalInfo", userAccount.getAdditionalInfo())),
new UpdateOptions().upsert(true));
}

View File

@ -12,16 +12,16 @@ import java.util.HashMap;
* LRU data is always at the end of the list.
*
*/
public class LRUCache {
public class LruCache {
class Node {
String userID;
String userId;
UserAccount userAccount;
Node previous;
Node next;
public Node(String userID, UserAccount userAccount) {
this.userID = userID;
public Node(String userId, UserAccount userAccount) {
this.userId = userId;
this.userAccount = userAccount;
}
}
@ -31,13 +31,16 @@ public class LRUCache {
Node head = null;
Node end = null;
public LRUCache(int capacity) {
public LruCache(int capacity) {
this.capacity = capacity;
}
public UserAccount get(String userID) {
if (cache.containsKey(userID)) {
Node node = cache.get(userID);
/**
* Get user account
*/
public UserAccount get(String userId) {
if (cache.containsKey(userId)) {
Node node = cache.get(userId);
remove(node);
setHead(node);
return node.userAccount;
@ -69,52 +72,63 @@ public class LRUCache {
public void setHead(Node node) {
node.next = head;
node.previous = null;
if (head != null)
if (head != null) {
head.previous = node;
}
head = node;
if (end == null)
if (end == null) {
end = head;
}
}
public void set(String userID, UserAccount userAccount) {
if (cache.containsKey(userID)) {
Node old = cache.get(userID);
/**
* Set user account
*/
public void set(String userId, UserAccount userAccount) {
if (cache.containsKey(userId)) {
Node old = cache.get(userId);
old.userAccount = userAccount;
remove(old);
setHead(old);
} else {
Node newNode = new Node(userID, userAccount);
Node newNode = new Node(userId, userAccount);
if (cache.size() >= capacity) {
System.out.println("# Cache is FULL! Removing " + end.userID + " from cache...");
cache.remove(end.userID); // remove LRU data from cache.
System.out.println("# Cache is FULL! Removing " + end.userId + " from cache...");
cache.remove(end.userId); // remove LRU data from cache.
remove(end);
setHead(newNode);
} else {
setHead(newNode);
}
cache.put(userID, newNode);
cache.put(userId, newNode);
}
}
public boolean contains(String userID) {
return cache.containsKey(userID);
public boolean contains(String userId) {
return cache.containsKey(userId);
}
public void invalidate(String userID) {
System.out.println("# " + userID + " has been updated! Removing older version from cache...");
Node toBeRemoved = cache.get(userID);
/**
* Invalidate cache for user
*/
public void invalidate(String userId) {
System.out.println("# " + userId + " has been updated! Removing older version from cache...");
Node toBeRemoved = cache.get(userId);
remove(toBeRemoved);
cache.remove(userID);
cache.remove(userId);
}
public boolean isFull() {
return cache.size() >= capacity;
}
public UserAccount getLRUData() {
public UserAccount getLruData() {
return end.userAccount;
}
/**
* Clear cache
*/
public void clear() {
head = null;
end = null;
@ -135,6 +149,9 @@ public class LRUCache {
return listOfCacheData;
}
/**
* Set cache capacity
*/
public void setCapacity(int newCapacity) {
if (capacity > newCapacity) {
clear(); // Behavior can be modified to accommodate for decrease in cache size. For now, we'll

View File

@ -6,22 +6,25 @@ package com.iluwatar.caching;
*
*/
public class UserAccount {
private String userID;
private String userId;
private String userName;
private String additionalInfo;
public UserAccount(String userID, String userName, String additionalInfo) {
this.userID = userID;
/**
* Constructor
*/
public UserAccount(String userId, String userName, String additionalInfo) {
this.userId = userId;
this.userName = userName;
this.additionalInfo = additionalInfo;
}
public String getUserID() {
return userID;
public String getUserId() {
return userId;
}
public void setUserID(String userID) {
this.userID = userID;
public void setUserId(String userId) {
this.userId = userId;
}
public String getUserName() {
@ -42,6 +45,6 @@ public class UserAccount {
@Override
public String toString() {
return userID + ", " + userName + ", " + additionalInfo;
return userId + ", " + userName + ", " + additionalInfo;
}
}

View File

@ -16,7 +16,7 @@ public class AppTest {
*/
@Before
public void setUp() {
AppManager.initDB(false); // VirtualDB (instead of MongoDB) was used in running the JUnit tests
AppManager.initDb(false); // VirtualDB (instead of MongoDB) was used in running the JUnit tests
// to avoid Maven compilation errors. Set flag to true to run the
// tests with MongoDB (provided that MongoDB is installed and socket
// connection is open).