再说tokyocabinet 及其扩展

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

1   如果直接编译的tokyocabinet java版的时候,./configure都不通过,因为缺少了编译时共享.h头文件,或者说,没有正确安装C语言版的tokyocabinet了.[如图]


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();
	}
}


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

再说tokyocabinet 及其扩展

保存的测试对象:
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

你可能感兴趣的:(java,c,redhat,ext,TokyoCabinet)