再说tokyocabinet 及其扩展

开场白:关于tokyocabinet的性能就不说了,但至于安装的话,我之前已经写过关于安装java版的tokyocabinet,但我觉得未够系统,所以决定还简短说说。。。。然后再说一下关于tokyocabinet原生的java API是不支持直接存取java对象的.但可以做些扩展让java tokyocabinet技术存取对象.

1 如果直接编译的tokyocabinet java版的时候,./configure都不通过,因为缺少了编译时共享.h头文件,或者说,没有正确安装C语言版的tokyocabinet了.[如图]
[img]http://kernaling-wong.iteye.com/upload/attachment/134306/6a8b01b3-008e-35d7-a8e5-26881c0aedcf.jpg[/img]

2 其实,首先可以从官方网站http://tokyocabinet.sourceforge.net/下载C语言的包,如何已经安装了C语言版,则只需要 cp -r tc*.h /usr/loca/include .然后就能编译安装java版的tokyocabinet了,因为java版只是一个对C语言调用的桥接,真正实现的还是C语言的程序,当然,我这里用默认的安装,亦可以指定目录安装,不过一定要让它们处于系统的环境变量中,否则,编译可以通过但是运行的时候就报.so文件连接出错了...
3 安装编译完后,在java版的解压目录下会有一个example目录,那都是测试文件,大家
同时还提供了一个makeFile文件,大家直接在此目录下make就可以生成测试的类文件了.


OK,上面就简单说过了,以下是说一下关于java版本的原生API是不支持存取java的对象,所以这里需要做一些扩展.

主扩展类:

package com.kernaling.ext;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.HashMap;

import tokyocabinet.HDB;

/**
*
* @author kernaling.wong
* @date 2009-09-07
*
* 此类显示对tokyocabinet的一个应用与扩展,主要是支持多索引读取
*
*/
public class TokyoCache {
private static volatile HashMap<String, TokyoCache> hMap = new HashMap<String, TokyoCache>();

private HDB hdb = new HDB();
private int MODE = HDB.OWRITER | HDB.OCREAT;
private String path = "";
private TokyoCache(String path,int MODE){
this.path = path;
if(!hdb.open(path, MODE)){
int ecode = hdb.ecode();
System.err.println("error code:" + ecode);
}
}
public synchronized static TokyoCache getInstance(String path){

return getInstance(path, HDB.OWRITER | HDB.OCREAT);
}

public synchronized static TokyoCache getInstance(String path,int MODE){
if(path == null | path.trim().equals("")){
return null;
}
TokyoCache tc = hMap.get(path);
if(tc == null){
tc = new TokyoCache(path,MODE);
hMap.put(path, tc);
}
return tc;
}

/**
*
* @param key
* @param value
* @return 原生的API支持直接保存字符串
*/
public boolean storeString(String key,String value){
if(key != null && !key.trim().equals("")){
return hdb.put(key , value);
}else{
return false;
}
}

/**
*
* @param key
* @return 原生API支持直接读取字符串
*/
public String getString(String key){
if(key != null && !key.trim().equals("")){
return hdb.get(key);
}else{
return null;
}
}

/**
*
* @param key
* 移走key的记录
*/
public void remove(String key){
if(key != null){
hdb.out(key);
hdb.sync();
}
}

/**
*
* @param keys
* @return 根据byte[]的key得到共value对象.原API并不支持,这里作了扩展
*/
public Object getObject(byte keys[]){
if(keys == null){
return null;
}

byte valus[] = hdb.get(keys);
if(valus == null){
return null;
}
ByteArrayInputStream bais = null;
ObjectInputStream ois = null;
try{
bais = new ByteArrayInputStream(valus);
ois = new ObjectInputStream(bais);
return ois.readObject();
}catch(Exception ex){
ex.printStackTrace();
}finally{
try{
if(bais != null){
bais.close();
}

if(ois != null){
ois.close();
}
}catch(Exception e){
e.printStackTrace();
}
}
return null;
}

/**
*
* @param keys
* @param value
* @return 原生API并不支持直接保存对象,这里作了扩展
*/
public boolean storeObject(byte keys[],Object value){
if(keys == null || value == null ){
return false;
}

ByteArrayOutputStream baos = null;
ObjectOutputStream oos = null;
try{
baos = new ByteArrayOutputStream();
oos = new ObjectOutputStream(baos);
oos.writeObject(value);
oos.flush();
return hdb.put(keys,baos.toByteArray());
}catch(Exception ex){
ex.printStackTrace();
}finally{
try{
if(baos != null){
baos.close();
}

if(oos != null){
oos.close();
}
}catch(Exception e){
e.printStackTrace();
}
}
return false;
}

/**
*
* @param key
* 移走一个 key 的对象的value
*/
public void remove(byte key[]){
if(key != null){
hdb.out(key);
hdb.sync();
}
}

/**
* 关闭对应的路径的tokyocabinet的对象
*/
public void close(){
TokyoCache tc = hMap.remove(path);
if(tc != null){
tc.hdb.close();
}
}

/**
* 清除所有的对象
*/
public void clearAll(){
hdb.vanish();
hdb.sync();
}
}


测试类:

package com.kernaling.test;

import com.kernaling.ext.TokyoCache;

public class Test {
public static void main(String[] args) {
TokyoCache tc = TokyoCache.getInstance("./Cache/test.tch");

//以下的构造方法中需要说明的是,open的模式中增加了HDB.ONOLCK 这个参数,
//表示同一份索引文件可以有多个程序同时读取(默认多个不同程序读取同一份索引是会阻塞的)
// HDB.ONOLCK 参考官方API文档,这个 参数表示 open without blocking ......
// TokyoCache tc = TokyoCache.getInstance("./Cache/test.tch",HDB.ONOLCK | HDB.OWRITER | HDB.OCREAT);
/**
* 以下演示了存取字符串
*/
System.out.println("========example of store and get String==========");
tc.storeString("hello", "kernaling.wong");
System.out.println("before key:"+"hello"+"\tvalue:"+"kernaling.wong"+"\t"+" has benn stored");
String value = tc.getString("hello");
System.out.print("after key:"+"hello"+"\tvalue:" + value);
System.out.println();
System.out.println();

/**
* 以下演示了存取java对象
*/


System.out.println("========example of store and get Object==========");
StoreObject so = new StoreObject("kernaling.wong");
System.out.println("befor key:" +so.getKey()+"\tvalues:" + so.prinrfInfo());

tc.storeObject(so.getKey().getBytes() , so);
System.out.println("storing key:" + so.getKey()+" ..... ");
StoreObject tSo = (StoreObject)tc.getObject(so.getKey().getBytes());
System.out.println("after key :" + tSo.getKey() +"\tvalues:" + tSo.prinrfInfo());

System.out.println();
System.out.println();

System.out.println("=============other operation below===================");

tc.remove("hello");
String tValue = tc.getString("hello");
System.out.println("key:"+"hello "+ "\tvalue:"+tValue);
System.out.println("key:" + "hello" +" has been remove");

tc.remove(so.getKey().getBytes());
System.out.println("key:"+"hello "+ "\tvalue:"+tValue);
System.out.println("key:" + "hello" +" has been remove");


System.out.println("Tc will be empty....");
tc.clearAll();
System.out.println("Tc will be closed");
tc.close();
}
}


运行以上的测试类的程序应该显示如下:

[img]http://dl.iteye.com/upload/attachment/143943/fd8408d0-53ad-3459-b4ec-5e3690eab2cf.jpg[/img]

保存的测试对象:

package com.kernaling.test;

import java.io.Serializable;

/**
*
* @author kernaling.wong
* 保存的对象一定需要implements 序列化接口
*/
public class StoreObject implements Serializable{
private String name = "";
public StoreObject(String name){
this.name = name;
}
public String getKey(){
return name;
}

public String prinrfInfo(){
return "java object values:" + name ;
}
}




后记:
这是对tokyocabinet的一个小扩展,当然很多功能都并未加上去,如:历遍,统计缓存里的个数等还未实现,有兴趣的朋友可以为其添加,同时这里的tokyocabinet暂时只是对key-value模式作一个扩展,table模式还未增加.我还提供了配置tokyocabinet运行环境的一个shell脚本,其他都是差不多根据官方文档来做的,测试环境 redhat 5.3 no xwindow jdk 1.6
欢迎转载,请注册出处与作者 kernaling.wong http://kernaling-wong.iteye.com/blog/464421
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值