背景
Darts是雙數組的c++ (template)實現,用來存儲、查詢大規模詞表非常方便。缺點是只能夠使用“字符串完全匹配”,而不能查詢“某個字符串是否是另外一個字符串的字串”這樣的需求。
如下原因結合起來,促使要在java codebase中使用Darts:
1. 詞表規模巨大,存儲、查詢效率很低
2. Darts是c++實現,現有Hadoop codebase是java的,無法直接使用
技術思路:
1. 用c++進一步包裝Darts接口(這一步必須要做,因為darts實現在.h中——template+inline牛B,默認使用方式是在c++project中直接包含頭文件就能調用相關接口),並生成動態鏈接庫
2. 用JNI(java native interface)進一步包裝動態庫,形成java接口
3. 在現有codebase中調用JNI
使用方法
這部分講如何使用已經包裝好的Darts。具體Darts是如何包裝的,後面再詳細說。
Darts JNI接口
接口定義在Darts.java文件中:
public class Darts {
public static native boolean BuildDict (String fileInput, String fileDictOutput);
public static native boolean LoadDict (String fileDict);
public static native boolean IsInDict (String term);
static
{
System.loadLibrary("Darts");
}
public static void main(String[] args) throws Exception {
System.out.println ("In this project, we test jni!\n");
……
} // main
}
三個接口,分別創建詞典、加載詞典和判斷某個字符串是否在詞典中。
創建Darts詞典
1.將詞典放到文本文件中,以UTF-8保存,在windows平台,UE中可以選擇“UTF-8-無BOM”
2.在java中調用BuildDict函數,輸入參數為步驟1中的文本文件,輸出為Darts格式的詞典文件,例如:在Darts.java的main函數中作如下調用:
Darts.BuildDict("/xxx/xxx_utf8.txt", "/xxx/xxx_utf8.dict");
3.運行上述調用程序,生成詞典文件
如果在windows + eclipse上直接運行,會提示找不到動態庫Darts,是在這裡調用的:
static
{
System.loadLibrary("Darts");
}
實際上是找不到libDarts.so文件。而且在windows環境下,.so文件也無法正常加載。解決方法是打成jar包,放到linux環境下,用‘-Djava.library.path’選項來指明.so文件所在的路徑,例如:
java-Djava.library.path='/xxx/MyDarts'-jar /xxx/tmp/DartsForJni.jar myDarts
我編譯的libDarts.so文件在'/xxx/MyDarts'路徑下。