`
kernaling.wong
  • 浏览: 78829 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

再说tokyocabinet 及其扩展

    博客分类:
  • java
阅读更多
开场白:关于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();
	}
}


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



保存的测试对象:
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
  • 大小: 55.2 KB
3
2
分享到:
评论

相关推荐

    tokyocabinet-1.4.30.tar

    它支持自动扩展,能够在数据量增加时保持良好的性能。但不保证元素的顺序,不适合进行范围查询。 2. TB2(B树数据库):采用平衡B树结构,适合于需要排序和范围查询的应用。TB2数据库在插入和查询性能上有所牺牲,...

    tokyocabinet

    东京暴君数据库的客户端封装,使东京暴君可以通过网络连接

    tokyocabinet-1.4.45.tar.gz

    这个名为"tokyocabinet-1.4.45.tar.gz"的压缩包文件包含的是Tokyo Cabinet的1.4.45版本源代码。在本文中,我们将深入探讨Tokyo Cabinet的主要特性和它在IT领域的应用。 Tokyo Cabinet的核心特点: 1. **键值对存储...

    tokyocabinet-1.4.47.tar.gz

    下载tokyocabinet-1.4.47.tar.gz后,解压并编译源码,通常包括configure、make和make install步骤。安装完成后,可以通过提供的示例代码了解如何使用Tokyo Cabinet的API进行数据库操作。 10. 社区支持与维护: ...

    tokyocabinet-1.4.48.tar.gz

    标题中的"tokyocabinet-1.4.48.tar.gz"表示的是Tokyo Cabinet的1.4.48版本的源码压缩包,它采用tar.gz格式进行打包,这是一种在Linux和类Unix系统中常见的文件归档和压缩方式。 Tokyo Cabinet提供了两种主要的数据...

    tokyotyrant/tokyocabinet/gpac

    标题 "tokyotyrant/tokyocabinet/gpac" 提及了三个关键组件:TokyoTyrant、TokyoCabinet 和 GPAC。...将它们结合使用,可以构建出适应现代互联网需求的高性能、可扩展的多媒体数据存储和处理系统。

    tokyocabinet安装配置总结(Ubuntu)

    Tokyocabinet是一款高效、轻量级的键值存储数据库,广泛应用于日志记录、缓存服务、数据索引等领域。Tokyocabinet提供多种数据结构,包括哈希表、B+树和直方图,支持多种数据类型,并且具有高度的可移植性和良好的...

    tokyocabinet源码分析

    - **xmsiz**:TCHDB的扩展MMAP内存大小。 - **rcnum**:缓存内存中的记录数量。 - **dbgfd**:调试信息级别,设置为1时启用调试模式。 #### 硬盘上哈希存储源码分析 硬盘上的哈希存储是Tokyocabinet中一种重要的...

    20091016通过spymemcached调用tokyocabinet网络接口的性能测试

    标题 "20091016通过spymemcached调用tokyocabinet网络接口的性能测试" 暗示了这篇文档可能涉及到的是一个关于优化数据存储和检索性能的技术测试。在这个测试中,作者可能使用了 `spymemcached` 这个Java库来与Tokyo ...

    tokyocabinet.cr:TokyoCabinet的Crystal客户端

    TokyoCabinet是一款高效、轻量级的数据库系统,它主要用C语言编写,提供了多种接口,包括C、C++、Perl、Python等。而`tokyocabinet.cr`是针对TokyoCabinet的一个Crystal语言客户端,使得在Crystal编程语言环境中可以...

    tokyocabinet-ruby-1.31.tar.gz_TOKYO_TokyoCabinet

    Tokyo cabinet C 库的 Ruby绑定代码API Tokyo cabinet 是一个管理数据库的库。该数据库是一个单一的数据文件,每个记录为关键字和值。每个关键字和值是可变长度的字节序。二进制数据和字符串都可作为关键字或值。...

    tokyocabinet中HDB和BDB引擎的存储速度比较

    标题中的“tokyocabinet”是一个轻量级的键值对数据库系统,它提供了两种不同的存储引擎:HDB(Hash Database)和BDB(Btree Database)。这两种引擎各有特点,适用于不同的场景。在进行存储速度的比较时,我们需要...

    tokyocabinet.jar

    Tokyo Cabinet 是日本人 平林幹雄 开发的一款 DBM 数据库,该数据库读写非常快,哈希模式写入100万条数据只需0.643秒,读取100万条数据只需0.773秒,是 Berkeley DB 等 DBM 的几...tokyocabinet.jar是该数据库的接口API

    httpsqs 安装包(httpsqs-1.7,libevent tokyocabinet)附上安装文档

    在IT行业中,消息队列(Message Queue)是一种重要的软件组件,用于在分布式系统中解耦应用程序,通过异步处理提高系统的可扩展性和稳定性。本文将详细介绍`httpsqs`,一个基于`libevent`和`tokyocabinet`的消息队列...

    Tokyocabinet-Tokyotyrant文档大合集

    Tokyo Cabinet 是一个DBM的实现。这里的数据库由一系列key-value对的记录构成。key和value都可以是任意长度的字节序列,既可以是二进制也可以是字符串。这里没有数据类型和数据表的概念。 当做为Hash表数据库使用时,...

    Python库 | pydory-1.1.41-cp38-cp38-macosx_10_9_x86_64.whl

    Python作为一种强大的编程语言,拥有丰富的第三方库支持,极大地扩展了其功能和应用领域。在给定的资源中,我们关注的是`pydory`库,版本1.1.41,它是一个为Python 3.8编译的 wheel 包,适用于macOS 10.9及更高版本...

    tokyocabinet-perl-1.34.tar.gz_TOKYO

    Tokyo cabinet C库的Perl绑定代码API。 Tokyo cabinet 是一个管理数据库的库。该数据库是一个单一的数据文件,每个记录为关键字和值。每个关键字和值是可变长度的字节序。二进制数据和字符串都可作为关键字或值。...

    tokyocabinet-java-1.24.tar.gz_TOKYO_Tokyo Cabinet java_tokyocabi

    Tokyo cabinet C 库代码的Java绑定接口。 Tokyo cabinet 是一个管理数据库的库。该数据库是一个单一的数据文件,每个记录为关键字和值。每个关键字和值是可变长度的字节序。二进制数据和字符串都可作为关键字或值。...

    tokyocabinet-lua-1.10.tar.gz_TOKYO_Tokyo Cabinet

    Tokyo cabinet C 库的Lua绑定接口。 Tokyo cabinet 是一个管理数据库的库。该数据库是一个单一的数据文件,每个记录为关键字和值。每个关键字和值是可变长度的字节序。二进制数据和字符串都可作为关键字或值。...

Global site tag (gtag.js) - Google Analytics