/*
* This file is part of the Wayback archival access software
* (http://archive-access.sourceforge.net/projects/wayback/).
*
* Licensed to the Internet Archive (IA) by one or more individual
* contributors.
*
* The IA licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.archive.wayback.util.bdb;
import java.io.File;
import java.io.UnsupportedEncodingException;
import java.util.Properties;
import org.archive.wayback.util.Timestamp;
import com.sleepycat.je.Database;
import com.sleepycat.je.DatabaseConfig;
import com.sleepycat.je.DatabaseEntry;
import com.sleepycat.je.DatabaseException;
import com.sleepycat.je.Environment;
import com.sleepycat.je.EnvironmentConfig;
import com.sleepycat.je.LockMode;
import com.sleepycat.je.OperationStatus;
/**
* Generic class for simple key-value pair lookup using BDBJE.
*
* @author oskar.grenholm@kb.se
* @version $Date$, $Revision$
*/
public class BDBMap {
// Acts as a mapping between an ID and a timestamp to surf at.
// The dir should probably be configurable somehow.
private static String BDB_DIR = System.getProperty("java.io.tmpdir") +
"/wayback/bdb";
private static Properties bdbMaps = new Properties();
protected Environment env = null;
protected Database db = null;
protected String name;
protected String dir;
/**
* consturctor
* @param name of database
* @param dir path of directory where dbd files should be stored. The
* directory is created if it does not exist.
*/
public BDBMap(String name, String dir) {
this.name = name;
this.dir = dir;
init();
}
protected void init() {
try {
EnvironmentConfig envConf = new EnvironmentConfig();
envConf.setAllowCreate(true);
File envDir = new File(dir);
if (!envDir.exists())
envDir.mkdirs();
env = new Environment(envDir, envConf);
DatabaseConfig dbConf = new DatabaseConfig();
dbConf.setAllowCreate(true);
dbConf.setSortedDuplicates(false);
db = env.openDatabase(null, name, dbConf);
} catch (DatabaseException e) {
e.printStackTrace();
}
}
/**
* persistantly store key-value pair
* @param keyStr
* @param valueStr
*/
public void put(String keyStr, String valueStr) {
try {
DatabaseEntry key = new DatabaseEntry(keyStr.getBytes("UTF-8"));
DatabaseEntry data = new DatabaseEntry(valueStr.getBytes("UTF-8"));
db.put(null, key, data);
} catch (DatabaseException e) {
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
/**
* retrieve the value assoicated with keyStr from persistant storage
* @param keyStr
* @return String value associated with key, or null if no key is found
* or an error occurs
*/
public String get(String keyStr) {
String result = null;
try {
DatabaseEntry key = new DatabaseEntry(keyStr.getBytes("UTF-8"));
DatabaseEntry data = new DatabaseEntry();
if (db.get(null, key, data, LockMode.DEFAULT) ==
OperationStatus.SUCCESS) {
byte[] bytes = data.getData();
result = new String(bytes, "UTF-8");
}
} catch (DatabaseException e) {
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return result;
}
/**
* @param context
* @return singleton BDBMap for the context
*/
public static BDBMap getContextMap(String context) {
if(context == null) context = "";
if(context.startsWith("/")) {
context = context.substring(1);
}
BDBMap map = null;
synchronized(BDBMap.class) {
if(!bdbMaps.containsKey(context)) {
File bdbDir = new File(BDB_DIR,context);
bdbMaps.put(context,new BDBMap(context,
bdbDir.getAbsolutePath()));
}
map = (BDBMap) bdbMaps.get(context);
}
return map;
}
/**
* return the timestamp associated with the identifier argument, or now
* if no value is associated or something goes wrong.
* @param context
* @param ip
* @return timestamp string value
*/
public static String getTimestampForId(String context, String ip) {
BDBMap bdbMap = getContextMap(context);
String dateStr = bdbMap.get(ip);
return (dateStr != null) ? dateStr : Timestamp.currentTimestamp().getDateStr();
}
/**
* associate timestamp time with idenfier ip persistantly
* @param context
* @param ip
* @param time
*/
public static void addTimestampForId(String context, String ip, String time) {
BDBMap bdbMap = getContextMap(context);
bdbMap.put(ip, time);
}
}