学习lucene索引文件格式的目的是通过对lucene数据结构的理解,从而为lucene索引实现打下基础。
索引文件的整体结构
如下图,这是整个索引文件的整体结构,可以看到,实际上lucene索引保存下了相当多的东西
但是,单从上面的文件罗列,很难看出来一个整体的结构,那么,接下来这张图就向我们展示这个结构,原图来源于网络,但是由于已经过时,我根据lucene最新的版本重新画了一张。如果相对比3.0版就会发现,一些文件后缀也被改变了,比如tis,tii变成新的tim,tip,另外,实际上del文件也没有使用了,究其原因是writer会动态计算被删除的文件,而不是写入文件。
索引文件中最重要的结构便是倒排索引了,如下图,其中Dictionary就是所有term的集合,放在tim和tip中,而posting list则存放文档id,词频和单词出现的位置,放在pos和doc中,其中doc存放的是词频,pos存放的是单词位置。
编解码器
索引的文件格式有可能会进化,一旦版本更新之后就不能再支持其他的索引文件格式,或者说一个lucene版本只能支持lucene自己的索引势必会降低lucene的灵活性,那么如何保持索引文件格式的灵活性和动态扩展性也是一个值得考虑的问题,lucene采用编解码器(codec)来实现这种灵活性。
编解码器是lucene中负责与索引文件直接读写的模块。所有的上层调用都基于编解码器,这是代码模块化的结果。我们来看编解码器的一些设计思想。
首先是LuceneXXCodec,这是Codec的直接实现者,不同的版本可能会实现不同的codec,例如,lucene4.5就是Lucene45Codec。codec的实现采用了facade模式,屏蔽了后面的所有format
因为不同的版本可能会有不同的格式,所以对应将这些格式抽象出来对于可扩展性就尤为重要了。也正是因为如此,lucene前面的版本和后面的版本格式可能差别会很大。对于我们了解lucene文件格式可能并不太好。但是lucene索引中许多精髓都类似,因而他们还是相通的,理解一种格式便于我们了解另一种。
在lucene4系列中,4.0的实现是所有格式中最全的,其他新版本可能或多或少依赖了老版本,所以可能你运行的是lucene4.5,但实际上看到的索引文件是Lucene41_0.doc。对于几个期望更灵活的类和格式,lucene采取注册查找的方式来获得。NamedSPILoader就是负责查找Codec,PostingFormat和DocValuesFormat的类,而注册的类会放在下面的文件里。org.apache.lucene.codecs.lucene41.Lucene41Codec便是配置在Codec中的。
索引文件格式的设计技巧
索引文件之所以是整个lucene的核心和关键,原因在于索引文件设计的好坏直接关系到时间和空间两方面因素。好的索引文件格式既要占用相对少的硬盘空间,又要支持搜索时尽可能快的查找。如果从这两方面衡量,会发现lucene中有许多精妙的设计,下面是一些罗列:
1. 文件的内容以数字和byte组成,而数字会根据需要自动变长,从而节省空间。下面分别是DataOutput和DataInput的writeVInt, readVInt的代码(writeVLong, readVLong),从这些代码中,我们可以看出来lucene是怎么做到自动变长的。
- public final void writeVInt(int i) throws IOException {
- while ((i & ~0x7F) != 0) {
- writeByte((byte)((i & 0x7F) | 0x80));
- i >>>= 7;
- }
- writeByte((byte)i);
- }
- public int readVInt() throws IOException {
- byte b = readByte();
- if (b >= 0) return b;
- int i = b & 0x7F;
- b = readByte();
- i |= (b & 0x7F) << 7;
- if (b >= 0) return i;
- b = readByte();
- i |= (b & 0x7F) << 14;
- if (b >= 0) return i;
- b = readByte();
- i |= (b & 0x7F) << 21;
- if (b >= 0) return i;
- b = readByte();
- // Warning: the next ands use 0x0F / 0xF0 - beware copy/paste errors:
- i |= (b & 0x0F) << 28;
- if ((b & 0xF0) == 0) return i;
- throw new IOException("Invalid vInt detected (too many bits)");
- }
下图就是自动变长的设计原理,注意,与我们的习惯不一样的是,这里是低字节在前,高字节在后,原因是要适应这里的流式处理,顺序的将字节写入文件。可以看到,为了适应变长的设计,每个字节只能使用7位,而变长整形最多能写入1-5个字节(本例为3字节),也就是35bit,实际上正好能容纳一个int(32bit)。
写入变长字节时先从整数的低字节处理,如果超过7个字节,则在第一个字节的第一个bit位置0,依次处理余下字节。
而读入变长字节时也是从低字节处读入,发现该字节如果小于0,说明后续仍然有字节需要处理(第1bit为1即补码为负),依次判断并处理下一字节;如果该字节大于0,则说明此变长字节处理完毕。
感慨lucene的设计者想出如此节省空间的方法,将一个bool型(8bit)缩减为1bit,并且简化了类型操作。而且代码也足够精巧,比如(i & ~0x7F) != 0,为什么要取0x7F的反呢,直接用0x80是不是更简单?但注意这里的i其实是一个整数,高位还有其他字节。
2. 差值(delta)。
差值的出现本质上是为了缩减存储空间,基于前面的自动变长,能够让差值工作得更顺畅。
如图,在许多地方都会存储一组从小到大的顺序值,或者将已有数据调整为顺序值,如果采用vint,则每个值都需要2个字节,但是采用差值方法来处理的话,除了第一个159需要2字节(根据自动变长,超过127的便会扩展到2字节),后面的5个数字都只需要1字节,如此便节省了空间。如果你对节省下来的这点空间不以为然,那么请将如下的int数组放大到G,就可以明白这其中的奥妙了。
3. 跳跃表(skip list)
跳跃表其实典型的是以空间换时间的方式,通过增加额外的存储空间(即索引)来更快速的定位元素位置。在lucene中,它被用来写入下面这3类文件,即doc,pos,pay
跳跃表的具体实现这里就不细讲了,MultiLevelSkipListWriter中有具体实现。这里仅浅显的讲讲跳跃表怎么工作的。跳跃表分为n层(默认为10),每层的跳跃间隔为s(默认为128,即块大小),每次搜索时从最高层开始定位,逐层向下找到元素(其思想有些类似二分搜索),可大幅缩减搜索时间。比如要查找20,首先查找第二层27,发现在27之后,于是查找第一层9,18,由于27大于20,于是查找第0层18,19,20
4. 压缩数组(packed array)
压缩数组主要目的是为了减少内存的浪费,比如这样的情况,当你申请16位整数时能存放16bit的二进制,但是一旦大于16bit(小于32bit) ,比如17bit,你就得申请32位整数来存放17bit,空间浪费率是47%。所以需要通过压缩数组来将数字打包成一块一块的,从而减少空间浪费。压缩数组的实现有很多方式,比如下图1中的跨block分割存储,或者图2中的跨block存储。lucene中的实现是取一个块的每个数据中最长的bit数来存放每个数据,在数据大小比较均匀的情况下,这种方式会浪费尽可能少的空间。在lucene中,真正实现这部分功能的类是ForUtil,BulkOperationPacked,BulkOperationPackedSingleBlock,PackedInts等,有兴趣的同学可以参考。关于压缩数组的参考资料,也在文末列出一部分。
索引策略
主要介绍下常见的建立索引的策略。
1. 2遍扫描法。所有操作在内存中进行,需要消耗大量内存,内存不足时无法完成索引操作。第一遍扫描主要做准备,得到一些全局的统计信息并且分配好接下来准备使用的内存;第二遍扫描则填充相应的信息到已分配好的内存中间。
2. 排序法。排序法在内存中分配固定大小的内存来存放词典和三元组(即单词ID,文档ID,单词频率),当内存不够时,将三元组合并到磁盘中,但是词典仍然驻留内存(一个hash表放在内存要快很多),词典在后期也会越来越大,导致可用内存越来越少。
3. 归并法。归并法则是在内存中建立一整套完整的索引,当内存不足时将整套新索引以类似更新索引的方式合并到旧索引中去。从lucene的实现来看,便是用类似这样的策略
lucene索引文件 http://www.cnblogs.com/forfuture1978/archive/2009/12/14/1623597.html
跳跃表 http://zh.wikipedia.org/wiki/%E8%B7%B3%E8%B7%83%E5%88%97%E8%A1%A8
压缩数组 http://blog.jpountz.net/post/25530978824/how-fast-is-bit-packing
http://software.intel.com/en-us/articles/paos-packed-array-of-structures
http://blog.csdn.net/liweisnake/article/details/10956645
相关推荐
(六)Lucene总结系列(二)--商品搜索系统的文字搜索业务(lucene项目使用)(七)Lucene总结系列(三)--总述优化方案并提供实时内存索引实现(结合RAMDirectory源码解析)(八)JavaWeb--Servlet过滤器Filter和...
每个分片都是一个独立的Lucene索引,可以被分配到集群中的任何节点上。这样不仅可以增加系统的吞吐量,还可以提高数据的可用性和容错性。 - **1.3.3. Replication** 复制(replication)机制允许为每个分片创建一...
区块链_智能合约_Solidity_保险应用_基于以太坊的技_1744433266
内容概要:本文档详细介绍了在Windows系统上安装MySQL数据库的具体步骤。首先,需要配置系统环境变量,包括新建MYSQL_HOME变量并将其添加到PATH中;其次,创建并编辑my.ini配置文件,设置MySQL的基本参数如端口、字符集、数据存放目录等;接着,在命令行工具中通过一系列指令完成MySQL的初始化、服务安装、启动以及root用户的密码设置和权限调整。整个流程涵盖了从环境搭建到最终确保MySQL服务正常运行的所有关键环节。 适合人群:适用于有一定计算机操作基础,尤其是对数据库管理有一定兴趣或需求的技术人员。 使用场景及目标:①帮助用户在本地机器上成功部署MySQL数据库环境;②确保用户能够掌握MySQL的基本配置与管理技能,如环境变量配置、服务安装与卸载、用户权限管理等。 其他说明:在安装过程中可能会遇到一些常见问题,例如由于之前版本残留导致的服务安装失败,此时可以通过命令行删除旧服务(sc delete mysql)来解决。此外,为了保证安全性,务必及时修改root用户的初始密码。
内容概要:`STARTUP.A51` 是 Keil C51 编译器自带的启动文件,用于初始化 8051 单片机的硬件和软件环境。该文件主要完成三个任务:初始化堆栈指针、清零内部数据存储器、跳转到主程序。文件中定义了内存模式(如 SMALL),并设置了堆栈指针的初始值为 0x60。接着通过循环将内部数据存储器的所有字节清零,确保程序开始时数据存储器的状态是确定的。此外,文件还列出了 8051 单片机的各个中断向量地址,并为每个中断提供占位符,实际的中断处理程序需要在其他文件中实现。最后,启动代码段初始化堆栈指针和数据段后,跳转到 `MAIN` 函数开始执行主程序。; 适合人群:对嵌入式系统开发有一定了解,尤其是使用 8051 单片机的开发者。; 使用场景及目标:①理解 8051 单片机启动文件的工作原理;②掌握如何初始化堆栈指针和数据段;③熟悉中断向量表的设置及其作用。; 其他说明:此文件为程序正常运行提供了必要的初始化操作,开发者可以根据具体需求修改该文件以适应不同的硬件和软件环境。
内容概要:该论文研究了一种基于行波理论的输电线路故障诊断方法。当输电线路发生故障时,故障点会产生向两侧传播的电流和电压行波。通过相模变换对三相电流行波解耦,利用解耦后独立模量间的关系确定故障类型和相别,再采用小波变换模极大值法标定行波波头,从而计算故障点距离。仿真结果表明,该方法能准确识别故障类型和相别,并对故障点定位具有高精度。研究使用MATLAB进行仿真验证,为输电线路故障诊断提供了有效解决方案。文中详细介绍了三相电流信号生成、相模变换(Clarke变换)、小波变换波头检测、故障诊断主流程以及结果可视化等步骤,并通过多个实例验证了方法的有效性和准确性。 适合人群:具备一定电力系统基础知识和编程能力的专业人士,特别是从事电力系统保护与控制领域的工程师和技术人员。 使用场景及目标:①适用于电力系统的故障检测与诊断;②能够快速准确地识别输电线路的故障类型、相别及故障点位置;③为电力系统的安全稳定运行提供技术支持,减少停电时间和损失。 其他说明:该方法不仅在理论上进行了深入探讨,还提供了完整的Python代码实现,便于读者理解和实践。此外,文中还讨论了行波理论的核心公式、三相线路行波解耦、行波测距实现等关键技术点,并针对工程应用给出了注意事项,如波速校准、采样率要求、噪声处理等。这使得该方法不仅具有学术价值,也具有很强的实际应用前景。
内容概要:本文详细介绍了光伏-混合储能微电网能量管理系统的模型架构及其控制策略。首先探讨了光伏发电模块中的MPPT(最大功率点跟踪)控制,采用扰动观察法和改进型变步长策略来提高光伏板的发电效率。接着重点讲解了混合储能系统的功率分配,利用一阶低通滤波算法将功率需求分为低频和高频两部分,分别由蓄电池和超级电容处理。此外,文中还深入讨论了SOC(荷电状态)管理策略,确保电池和超级电容在不同工作状态下保持最佳性能。仿真结果显示,在光伏出力剧烈波动的情况下,系统能够有效地维持稳定的电压水平,并显著提高了储能设备的使用寿命。 适合人群:对光伏微电网、储能技术和能量管理系统感兴趣的科研人员、工程师和技术爱好者。 使用场景及目标:适用于研究和开发高效、可靠的光伏-混合储能微电网系统,旨在优化能量管理和提高系统稳定性。具体应用场景包括但不限于家庭光伏系统、小型微电网以及工业能源管理系统。 其他说明:文中提供了详细的代码实现和仿真结果,便于读者理解和复现实验。同时,模型设计采用了模块化思路,方便进行个性化修改和扩展。
内容概要:本文详细介绍了基于MATLAB和CVX平台实现的储能调峰调频联合优化模型。该模型不仅涵盖了储能的基本参数设定、负荷不确定性处理、充放电策略制定,还包括了调峰调频的联合调度、功率约束处理、鲁棒优化等方面的内容。通过构建考虑电池退化成本、充放电功率约束以及用户负荷不确定性的储能优化模型,展现了储能系统在电力系统中的高效协同工作。文中提供了详细的代码示例,解释了各个部分的功能和实现方法,强调了模型的深度与创新性。 适合人群:适用于具有一定编程基础和技术背景的研究人员、工程师以及希望深入了解储能系统优化的学生。 使用场景及目标:该模型主要用于电力系统中储能设备的优化调度,旨在提高储能系统的经济效益和社会效益。通过联合调峰调频,能够显著提升储能系统的收益,实现1+1>2的超线性增益效果。此外,该模型还可以用于教学和科研,帮助初学者理解和掌握储能优化的相关技术和理论。 其他说明:代码中包含了丰富的注释和模块化的子程序,使得整个模型易于理解和扩展。对于有经验的开发者,可以在现有基础上进一步改进和定制,以适应不同的应用场景。
大模型技术白皮书2023版
图像增广 PyTorch 版
批量修改文件名可以帮助用户节省大量时间,提高工作效率 里面附带使用教程
《计算机应用基础》第2章--Windows-XP操作系统.ppt
包括:源程序工程文件、Proteus仿真工程文件、电路原理图文件、配套技术手册、论文资料等 1、采用51/52单片机(通用)作为主控芯片; 2、采用1602液晶显示使用过程及状态,液晶屏亮度会随光线自动调整; 3、按键输入6位密码,输入密码正确则锁打开,显示open!输入密码错误次数超过3次,蜂鸣器报警并且锁定键盘; 4、密码可以自己修改,必须是锁打开时才能改密,为防止误操作,修改密码得输入两次; 5、采用24C02保存密码,掉电不丢失; 6、可通过红外遥控器输入密码操作锁的状态;
内容概要:本文深入剖析了2025年全球感知技术的十大发展趋势,涵盖多模态感知融合、3D感知与空间计算、脑机接口中的感知反馈技术、5G/6G赋能的超低延迟感知、语音与情感识别的高级化、生物感知与数字健康、环境感知与自适应智能、增强现实(AR)与触觉反馈技术、气味与化学感知、量子感知与极端条件测量。文章详细介绍了每项技术的技术原理、关键算法、实现方式、商业案例及未来前景,强调了感知技术在智慧城市、自动驾驶、智慧医疗、工业自动化等领域的深刻影响。报告指出,感知技术正从单一传感模式向多模态融合、从二维数据向三维空间重建、从传统网络通信向超低延迟和高可靠性网络升级,实现全场景、全维度的智能感知。; 适合人群:对感知技术感兴趣的科技爱好者、研究人员、决策者、企业管理层和投资人。; 使用场景及目标:①了解感知技术的最新进展和未来发展方向;②为技术研究提供全面、深入的参考;③为商业应用提供具体的案例和前景分析;④推动跨领域协同创新,构建开放共赢的产业生态。; 其他说明:报告基于近年来技术研发的最新进展、业界前沿的技术路线以及各大科技企业在商业落地方面的丰富实践。随着感知技术的不断成熟,数据隐私与安全保护问题也需高度重视,以确保技术进步与社会伦理和谐统一。未来,感知技术将成为推动社会进步和产业升级的重要力量,为实现万物互联、智慧决策和智能体验提供无限可能。
本论文主要论述了如何使用JAVA语言开发一个校园新闻网站 ,本系统将严格按照软件开发流程进行各个阶段的工作,采用B/S架构,面向对象编程思想进行项目开发。在引言中,作者将论述校园新闻网站的当前背景以及系统开发的目的,后续章节将严格按照软件开发流程,对系统进行各个阶段分析设计。 校园新闻网站的主要使用者分为管理员和用户,实现功能包括管理员:首页、个人中心、用户管理、新闻类型管理、校园新闻管理、留言板管理、论坛交流、系统管理,用户前台:首页、校园新闻、论坛交流、留言反馈、个人中心、后台管理等功能。由于本网站的功能模块设计比较全面,所以使得整个校园新闻网站信息管理的过程得以实现。 本系统的使用可以实现本校园新闻网站管理的信息化,可以方便管理员进行更加方便快捷的管理,可以提高管理人员的工作效率。 基于Springboot+vue的校园新闻网站【源码+数据库+参考论文】 感兴趣自行下载学习!
内容概要:本文详细探讨了三相三电平PWM整流器的闭环控制策略及其核心技术——三电平SVPWM算法。文章首先介绍了三相三电平PWM整流器的基本概念和优势,如输出三种电平以降低谐波含量并减少滤波器体积和成本。接着阐述了闭环控制策略的重要性,强调了电压外环和电流内环的双闭环控制机制。随后,文章深入讲解了三电平SVPWM算法的工作原理,包括空间电压矢量的选择、扇区判断、矢量作用时间和死区补偿等关键技术环节。此外,还讨论了中点电位平衡的问题以及PI参数的整定方法。最后,通过示波器测试验证了系统的性能指标,如THD低于3%,直流电压纹波小于1%。 适合人群:从事电力电子领域的工程师和技术人员,尤其是对三相三电平PWM整流器及其控制策略感兴趣的读者。 使用场景及目标:适用于高压大功率场合,旨在提高整流器的性能,降低谐波含量,实现单位功率因数运行。通过合理设计闭环控制策略和优化SVPWM算法,确保整流器在各种工况下都能稳定、高效地工作。 其他说明:文中提供了大量MATLAB和C语言代码片段,帮助读者更好地理解和实现相关算法。同时,针对实际调试过程中遇到的问题给出了实用的解决方案,如中点电位平衡和死区补偿等。
全新红娘本地交友系统定制版源码 相亲婚恋交友小程序源码
内容概要:文章探讨了AI技术,特别是DeepSeek,如何驱动地图生成的变革。首先介绍了地图制图在AI时代的背景与挑战,强调了DeepSeek与地图融合的两种主要方式:嵌入地图制图链和研发地图语言自身的预训练模型。随后详细描述了DeepSeek在地图生成中的具体应用,包括智能化地图生成器DoMapAI的整体框架,地图制图链中的知识图谱推理路径,以及地图语言的Token化过程。最后,文章总结了AI时代地图制图的职业变化和技术变革,指出地图制图正经历“大变局”。 适合人群:从事地图制图及相关领域的研究人员、工程师,以及对AI与地图生成感兴趣的学者。 使用场景及目标:①理解AI技术在地图生成中的应用,特别是DeepSeek的作用;②掌握智能化地图生成器DoMapAI的工作原理及其应用场景;③学习地图语言Token化的方法及其在地图生成中的应用;④探索AI时代地图制图的职业发展方向和技术变革。 阅读建议:本文内容较为专业,建议读者先了解基本的AI技术和地图制图知识。重点关注DeepSeek与地图融合的具体方法和应用场景,理解智能化地图生成器DoMapAI的工作流程,以及地图语言Token化的实现过程。在阅读过程中,可以结合实际案例进行思考,以更好地理解AI技术对地图制图的影响。
chromedriver-mac-arm64-135.0.7049.114.zip
《网络布线与小型局域网搭建(第2版)》第3章-布线系统的设计.ppt