lucene splitRange 切割区间的原理

来源:互联网 发布:台湾诈骗犯 知乎 编辑:程序博客网 时间:2024/05/04 03:22

 

关于lucenesplitIntRange(final IntRangeBuilder builder,final int precisionStep,final int minBound, final int maxBound)splitLongRange(finalLongRangeBuilder builder,final int precisionStep, final long minBound, final longmaxBound)这两个方法,在相关的技术论坛很少有提及的,就算有提及的,好像也只是蜻蜓点水一样。通过昨天一天的思考,对这个算法有了点认识,就想把这个想法分享一下。

 

1.      首先这两个方法是把一个区间分割成几个区间,这几个区间是相互之间不会重复的。这点必须认识到。

2.      为什么会有两个方法,因为切割的对象不同,一个针对int;一个针对long。(不过最终它们还是调了同一个方法,也就是splitRange(final Object builder, final int valSize,final intprecisionStep, long minBound, long maxBound)

 

 

 

我没有具体的来阐述代码,只是把最后的这个方法的原理阐述一下,之后就可以根据这个原理对照着代码进行阅读,相信是事半功倍的。下面开始:

 

这个方法像上面所说的是把一个区间切割,所以举个例子,比如说现在要切割区间[1-12340],

如果按照十进制的切割法,应该被切割成

[0][1-9]------------------------>1-9

[1][1-9]------------------------>10-99

[2][1-9]------------------------>100-999

[3][1-11]----------------------->1000-11999

[2][120-122]----------------->12000-12299

[1][1230-1233]-------------->12300-12339

(第一个数字代表位数)

 

上面说的是十进制的,现在如果把它切换成16进制的话,就变成了下面这样:原区间[00,00,00,01-00,00,30,34],切割之后:

[0][00,00,00,01-00,00,00,0f]------------------>[00,00,00,01-00,00,00,0f]--------------->[1-15]

[1][00,00,00,1-00,00,00,f]--------------------->[00,00,00,10-00,00,00,ff]---------------->[16-240]

[2][00,00,01-00,00,0f]-------------------------->[00,00,01,00-00,00,0f,ff]----------------->[256-3840]

[3][00,00,1-00,00,2]----------------------------->[00,00,10,00-00,00,2f,ff]----------------->[4096-8192]

[1][00,00,30,0-00,00,30,2]-------------------->[00,00,30,00-00,00,30,2f]---------------->[12288-12320]

[0][00,00,30,30-00,00,30,34]----------------->[00,00,30,30-00,00,30,34]--------------->[12336-12340]

 

再把最后的十进制区间转换成lucene内部存储数字的字符串格式,也就是调用intToPrefixCoded(final int val, final int shift, final char[]buffer)或者

longToPrefixCoded(final long val, finalint shift, final char[] buffer)

调完了之后变成了下面这样:

[1-15]----------------------------------->[60,08,00,00,00,01-60,08,00,00,00,0f]

[16-240]------------------------------->[64,40,00,00,01-64,40,00,00,0F]

[256,3840]---------------------------->[68,04,00,00,01-68,04,00,00,0F]

[4096-8192]-------------------------->[6C,20,00,01-6C,20,00,02]

[12288-12320]----------------------->[64,40,00,06,00-64,40,00,06,02]

[12336,12340]----------------------->[60,08,00,00,60,30-60,08,00,00,60,34]

下面来说为什么要转换成16进制。因为数字格式在lucene中是被存储成字符串的。而且这些字符串是以trie树的形式存储的。这些trie树的父节点都是自己点右移4为形成的,所以要以16进制来计算。这里并不讨论lucene是怎样把数字存储成字符串的,这方面的资料网上很多。

讲到这里原理基本上讲完了,如果关于lucene的问题,都可以发信给我,一起讨论。

 

 

 

 

原创粉丝点击