Apache Lucene的结构

不可估量的高贵的Apache软件基金会(Apache Software Foundation)产生了许多重要产品(Ant,CouchDB,Hadoop,JMeter,Maven,OpenOffice,Subversion等),这些产品有助于构建我们的数字世界。 Lucene也许是一个鲜为人知的瑰宝,它“……提供基于Java的索引和搜索技术,以及拼写检查,命中突出显示和高级分析/令牌化功能。” 尽管从标题上避开了,Lucene还是许多Apache(和第三方)项目中一个安静但不可或缺的组成部分。

lucene-package-anim

让我们看一下这个出色且非常成功的产品的基础结构。

在开始之前,请先进行以下四个警告。

  1. 作为一种语法结构分析,此评论对程序语义或无论多么精致的交付用户体验都不太在意。
  2. 结构本身值得进行调查,因为它支配着变更潜在成本的可预测性。 结构不良的系统表现出过度的互连性,其中的连锁反应会严重影响变更成本估算的准确性。 结构良好的系统维护和升级的费用不一定便宜,但是通常它们带来的麻烦更少。
  3. 该分析将包装结构描绘为斯皮克林图 ,其中圆圈表示包装,直线表示从上方绘制的包装到下方绘制的包装的依赖性,而曲线线表示从下方绘制的包装到上方绘制的包装的依赖性。 。 程序包的颜色表示它所参与的可传递程序包依赖关系的相对数量:红色,可传递程序依赖关系越多。
  4. 没有图可以证明结构价值或成本。 高级分析仅在提示问题的答案被埋在代码的地质层之下时才进行。

因此,为了生意……

崛起 …

图1:Lucene 1.4.3版的软件包结构。

图1:Lucene 1.4.3版的软件包结构。

图1显示了仍在归档的Lucene的最早版本之一,版本1.4.3。 回想一下,简单的结构测试表明随机选择了一个程序包,并询问:“如果该程序包发生更改,它最有可能影响其他哪些程序包?”

索引为例。 很明显的QueryParser跨度都依赖于它,因此可以通过任何变化指标受到影响,而曲线显示, 搜索就靠它呢。 这种易于识别的依赖性体现了整个人物的特征,使其结构合理。

布拉沃(Bravo),露西恩(Lucene),您的开局很好。

图2:Lucene 2.0版的程序包结构。

图2:Lucene 2.0版的程序包结构。

图2显示了2.0版(请注意,我们不会研究每个发行版,而是沿着整个发行路径均匀地划分里程碑),并且互连的简单性仍在继续。 尽管方法的数量从1.4.3的1,637版增加到2.0的2,085版,但程序包的数量却从11种减少到10种。这促使有效耦合效率从41%降至37%略有下降,但是好的设计原则显然可以精通此系统。

图3:Lucene 2.4版的软件包结构。

图3:Lucene 2.4版的软件包结构。

上面的图3中呈现的2.4版本虽然远没有明显的不良结构,但是却显示出苦恼的最初迹象。

没错,许多包裹与邻居之间有着明显的联系。 但是现在有些没有。 特别是搜索索引似乎已经陷入彼此的事务中。

但是,这种轻微的结构退化掩盖了幕后发生的动荡变化。 在2.0版有2,085个方法的地方,2.4版的大小增加了一倍多,达到4,176个方法。 在版本2.0仅具有9,767个传递依赖项的情况下,版本2.4在繁重的48,370个传递依赖项之下下垂。 正如我们将看到的那样,某些结构性裂缝已在方法级别上深层拉开,以触发依赖关系的五倍增长,这是Lucene的程序员从未发现或密封的裂缝,并且困扰着以后的修订。

不仅依赖关系的数量急剧增加,而且程序的深度(其传递依赖关系的平均长度)也增加了,从2.0版的7升级到2.4版的8.6,不仅在涟漪效应可能会扑朔迷离,但将这些音轨延伸到更远的地方以分流虚假的冲击。

尽管如此,这种结构仍然没有解决任何问题。 专注于设计可以恢复早期版本所具有的简单性。

图4:Lucene 3.0版的程序包结构。

图4:Lucene 3.0版的程序包结构。

las,版本3.0(如上图4所示)似乎继续以很小的幅度下降。 再次,图4并没有呈现出一种不可挽回的结构:我们可以通过拆开包装来了解它们之间如何相互连接。 但是,这项任务变得更加困难。

分析跨度都被搜索索引所吸引。 预测更改这四个软件包中任何一个的影响现在似乎需要对所有其他软件包进行自动调查。

为增加互连性做出的贡献是在此修订版中增加了800种方法。 即使传递依存关系的数量已下降到46,917个,但平均长度仍再次增加,这次是9.3个。

系统的结构是否超出希望? 一点也不:许多软件包与同事之间都享有明确的依赖关系。 然而,即将到来的是版本3.5和大量传递依赖,尽管不是立即致命,但证明对所有药物都具有抗药性。

还有秋天……

图5:Lucene 3.5版的程序包结构。

图5:Lucene 3.5版的程序包结构。

令人欣慰的是,如上图5所示,版本3.5引入了额外的三个软件包(总数达到18个),以尝试分发和分离系统的功能。 慷慨的还可能会提出,尽管软件包的结构已从上一版明显地再次衰减了,但这种衰减仍然在一定程度上是局部的:坏男孩分析跨度搜索索引继续使Lucene镇表现良好的其他人群感到恐惧。

但是慷慨到此为止。

尽管仅增加了1800种方法,修订版3.5的传递依赖项数量却猛增到109,357,并且这些依赖项的平均长度达到11种方法,这在整个演进中都是可悲的最大值。 考虑到结构复杂性的显着提高,我们想知道封装设计的外观如何,以及它的协调性确实是短暂的,因为应变最终破坏了下一个修订里程碑中的所有控制外观。

图5:Lucene 4.0版的程序包结构。

图5:Lucene 4.0版的程序包结构。

如图5所示,修订版4.0在以前的修订版中增加了1600种方法,使总数增加到8474,并且传递依赖项的数量相对适度地增加到116211,但是从图中可以看出,发生了一些可怕的事情。

先前版本的Swift发展的互连性突然系统化,导致结构内陷到可怕的缠结的依赖关系中,这使得代码影响预测变得非常不可靠。

的确,此修订版增加了另外两个软件包-将潜在的耦合效率提高到43%-并将传递依赖项长度(略)减少到10.4,但是控制如此大量的传递依赖项的巨大努力只是破坏了系统。 它不会恢复。

图6:Lucene 4.5版的软件包结构。

图6:Lucene 4.5版的软件包结构。

在图6所示的修订版4.5中,一些英勇的行动将传递依赖项的数量减少到106,242,同时仍将方法的数量增加到9,562,也许某些软件包设法使自己远离系统上手动旋转的贪婪黑洞。核心。 但是工作太少了,太迟了。

图7:Lucene 5.0版的程序包结构。

图7:Lucene 5.0版的程序包结构。

如图7所示,修订版5.0尝试通过删除200种方法来驯服野兽,但这奇怪地导致可传递依赖项的数量再次增加到113,556。

版本5.0看起来和版本4.5一样糟糕吗? 好吧,也许不是。 看起来有点干净。 但是,我们不应该让这种情况使我们对图7所示的巨大混乱视而不见:该系统痛苦不堪。 预测更改任何这些中央软件包的成本已经变得很困难。

为什么?

要了解破坏系统初始结构完整性的原因,我们必须检查3.5版。 再次,这看起来可能不是最糟糕的结构,但是此修订版预示了最终导致破产的变化。

主要的变化不仅是规模上的变化:更大的系统不一定会陷入不良的结构。 修订版3.5将方法数量增加了35%,但修订版2.4将方法数量增加了100%以上,而不会破坏整个组织。

相反,罪魁祸首是传递依赖项的数量及其在系统中的分布。

修订版3.5中引入的新的传递依赖项数量惊人,从46,917增至109,357。 这使依赖方法比达到了动脉硬化16。

图8:比较Lucene的方法传递依存关系比率。

图8:比较Lucene的方法传递依存关系比率。

依赖于方法的比率已经太高了。 但是,在以前的版本中,这些可传递依赖项在很大程度上只限于一个或两个程序包。 在版本3.0中,所有传递方法依赖项的95%终止于其原始包或仅一个依赖项的包中。 这给了希望,从某种意义上讲,变更可能会将自己限制在接近原点的区域,而很少有变更能够溢出到整个系统中,并且无法进行成本预测。

但是,修订版3.5看到该数字暴跌至75%。 这意味着所有修订版3.5的传递依赖项中有25%溢出到三个或更多程序包中。 将这两个因素结合在一起,就可以发现有33,000多个依赖项需要等待远远超出其起源的弹射变化。 最重要的是,这注定了产品会进一步结构衰减。

图9:Lucene传递依赖项所占的百分比,少于3个包。

图9:Lucene传递依赖项所占的百分比,少于3个包。

然后,这结束了对Lucene包级别结构的检查。 我们是否应该深入研究套餐级别? 我们是否应该梳理各个软件包以检查各种类别的星座? 不行 。根据Blighttown的推论 ,如果包装级别的结构不好,我们不希望在下面找到钻石。 所以我们不会。

最终成绩

让我们尝试对Lucene的结构进行客观评分(其最终修订版本此处为5.0)。

我们将使用四个因素的平均值。 第一个度量Lucene试图限制可能形成的依赖关系数量的尝试。 第二和第三次尝试捕获传递依赖项的长度,第四次尝试捕获传递依赖项的数量。 当然,大型系统总会比小型系统具有更多的依赖关系,因此我们不能仅仅因为系统A的依赖关系少就说系统A的结构比系统B更完善。 取而代之的是,我们必须通过标准化大小或使测量在某种意义上具有自参考性,得出可以公平比较的测量。

首先,我们将测量其绝对理想效率:这将分析结构的潜在耦合 ,并基本询问封装了多少种方法而不使用其他方法,因此可以想象会创建多少依赖关系。 如果将每种方法都放在一个类中,则每种方法对彼此都是可见的,因此效率为0%。 随着将更多方法设为私有并放入单独的包私有类中,其价值将不断提高,从而使方法之间的封装越来越多。

Lucene得分为44%,表明它至少已尝试封装其功能,但是可以做更多的事情。

其次,我们将以一种允许程序之间公平比较的形式来衡量Lucene的传递依赖项的长度。 为此,我们将使用CDF图来显示Lucene的传递方法依赖关系占其最长传递依赖关系的百分比。

图10:Lucene的传递依赖CDF。

图10:Lucene的传递依赖CDF。

在上面的图10中,我们看到Lucene的传递依存关系的一半短于最长的传递依存关系的长度的45%。 这是不好的。 系统对纹波效应的抵抗力取决于其大部分依赖关系是否短暂。 例如, JUnit的传递依赖的一半仅占其最长依赖关系长度的30%。

当我们需要一个具有改进结构的数字时,我们将使用100减去该数字,因此Lucene将获得100 – 45 = 55的分数,该值应接近70。

我们将要讨论的第三个因素是:跨越两个或更少程序包的方法所占的百分比,这个数字为75.5%。 听起来不错,但是使用现代结构技术 ,几乎没有理由将该值小于90%。

最后,我们需要一个因素来衡量系统中有多少依赖项,因为依赖项的数量越少越好。 为了规范化大小,我们要测量每个方法的方法相关性数量。 不幸的是,在这里我们必须估算出行业最低的分数。 一些研究表明25似乎是一个合适的数字:如果系统每个方法包含25个以上的依赖项,则该系统的结构是如此糟糕,以至于所有其他所有其他指标都失去了重要性。

前面我们看到,Lucene每个方法有12个巨大的依赖关系; 因此我们将使用的数字为25-12 = 13,以25的百分比表示,得出52%。 如图8所示,其他系统的每种方法的依赖关系低至6,这个指标的收益率超过70%。

这使得Lucene的最终得分为226.5 / 400分,即57%。 凭借坚定的结构原则,现代程序的分数很容易超过80%,所以这是一个很差的分数,表示,很糟糕的结构。 Lucene在本系列到目前为止所分析的系统的排行榜中排名倒数第二。

因子 得分了
绝对势偶效率% 44
100 –(最长依赖关系长度的一半,即一半系统短于该长度) 55
方法传递相关性百分比,范围不超过2个软件包 75.5
((25-(每个方法的传递方法依赖项数量)/ 25),以25的百分比表示 52
平均 57%

表1:Lucene 5.0的结构评估。

摘要

程序 结构得分
Spoiklin Soice 84%
JUnit的 67%
Struts 67%
FitNesse 62%
弹簧 60%
Lucene 57%
蚂蚁 24%

表2:Lucene在排行榜上的位置。

可以做的更好。

翻译自: https://www.javacodegeeks.com/2015/05/the-structure-of-apache-lucene.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/360306.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

comcerter无法识别串口_基于FPGA 的MXN维字符识别的实现

基于FPGA 的MXN维字符识别的实现1 概述本文的灵感来源于杨淑英老师的一张PPT(手写数字识别),在此特别鸣谢杨淑英老师。一般机器视觉对事物是没有感知的,比如摄像头采集到一张苹果的图片,它本身是不知道那是什么东西&am…

构造函数必须没有代码

构造函数中应完成多少工作? 在构造函数内部进行一些计算然后封装结果似乎是合理的。 这样,当对象方法需要结果时,我们将准备好它们。 听起来是个好方法? 不,这不对。 这是一个坏主意,原因有一个&#xff1a…

一个路由器两个网段互通_如何判断两个IP地址是否在同一个网段?什么是子网掩码?...

前几天咱们了解:三种方法告诉你项目超过255个摄像机怎么设置IP?什么是公网ip?什么又是内网ip?为什么ip地址通常以192.168开头?也学习了:二、三层交换机与路由器的区别!但是有好多人对IP这个概念还是不太清…

http 路径 |_HTTP 请求與响应的格式及 curl 命令使用

介绍 HTTP,主要内容有HTTP 请求包括哪些部分,如何用Chrome开发者工具查看 HTTP 请求内容HTTP 响应包括哪些部分,如何用Chrome开发者工具查看 HTTP 响应内容如何使用 curl 命令HTTP 请求的格式1 动词 路径 协议/版本 2 Key1: value1 2 Key2: v…

华为y7可以人脸识别吗_华为手机经常弹出“系统更新”提示,可以不更新吗?看完涨知识了...

众所周知,无论是手机,还是电脑,我们所使用的系统到了一定的时间,都会进行“系统更新”,尤其是我们使用的苹果手机、华为手机等,就经常会跳出提示,提醒用户“更新系统”,尤其是当我们…

Apache骆驼丝攻示例

如果您想监视,调试,排除流经路由的消息,而又不必从通道中永久消耗消息,那么就需要使用电线 。 有线分流器充当接收者列表,该列表消耗输入通道之外的消息并将其发布到两个输出通道。 第一个是作为主要信道的实际目的地…

参考文献中会议名称怎么缩写_期刊缩写查询总结

介绍英文论文写作中,经常会插入参考文献。那么参考文献中的期刊名称,时常需要使用缩写。但是有时候,查了半天,怎么也查不着,让人抓狂。今天小编总结了几个查询期刊缩写的网址,方便大家进行期刊缩写的查询。…

7. SVM松弛变量

我们之前讨论的情况都是建立在样例线性可分的假设上,当样例线性不可分时,我们可以尝试使用核函数来将特征映射到高维,这样很可能就可分了。然而,映射后我们也不能100%保证可分。那怎么办呢,我们需要将模型进行调整&…

mysql 8.0认证失败_解决mysql8.0因密码认证插件导致的链接不上

简介今天在迁移zabbix的数据库,每次链接到自己的mysql都报错,mysqlAuthentication plugin caching_sha2_password cannot be loaded: /usr/lib64/mysql/plugin/caching_sha2_passwordzabbix总是提示**** MySQL server is not available. Waiting 5 secon…

ActionScript 3.0入门:Hello World、文件读写、数据存储(SharedObject)、与JS互调

近期项目中可能要用到Flash存取数据,并与JS互调,所以就看了一下ActionScript 3.0,现把学习结果分享一下,希望对新手有帮助。 目录 ActionScript 3.0简介 Hello World 文件读写 数据存储(SharedObject) 与JS互调 ActionScript 3.0简…

Quasar和Akka –比较

actor模型是用于容错和高度可扩展系统的设计模式。 角色是独立的工作程序模块,仅通过消息传递与其他角色进行通信,可以与其他角色隔离而失败,但是可以监视其他角色的故障并在发生这种情况时采取一些恢复措施。 参与者是简单,孤立但…

dlgdata.cpp错误提示 解决方案

1、在测试编写继承CStatic类组件时候,发现在调用调试过程中弹出一个错误,点忽略还可以继续运行。如下图: 2、dlgdata.cpp此文件是VS安装目录\Microsoft Visual Studio .NET 2003\Vc7\atlmfc\src\mfc中的文件,而出现此错误一般是所…

mysql主从复制时间配置_MySQL主从复制配置

环境CentOS 7.5Docker 1.13.1MySQL 8.0.16基于以上环境启动三个mysql容器,一个为master,二个为slavemaster和slave使用的mysql版本是完全一致的,未测试不同版本的mysql配置master编辑配置文件编辑master的配置文件my.cnf$ vim /usr/mysql/con…

C语言操作符优先级

转自:http://www.cnblogs.com/xiehy/archive/2010/02/04/1663825.html 优先级 运算符 含 义 要求运算 对象的个数 结合方向 1 () [] -> . 圆括号 下标运算符 指向结构体成员运算符 结构体成员运算符 自左至右 2 ! 逻辑非运算符 1 (单目运算符)…

Win7下硬盘安装Redhat双系统

Win7下硬盘安装Redhat Linux 形成双系统过程详解 需要软件 EasyBCD2.0 和 linux ISO 系统镜像 RedHat linux下载地址:http://www.linuxidc.com/Linux/2013-01/78017.htm 安装前准备工作: 1 一个 Windows 盘 D E F 任选其一都可以,将其格式化为FAT32 格式…

java rmi漏洞工具_学生会私房菜【20200924】Weblogic WLS核心组件反序列化命令执行突破(CVE20182628)漏洞复现...

学生会私房菜学生会私房菜是通过学生会信箱收集同学们的来稿,挑选其中的优质文档,不定期进行文档推送的主题。本期文档内容为:Weblogic WLS核心组件反序列化命令执行突破(CVE-2018-2628)漏洞复现》作者介绍:ChowChow,一…

ASP.NET伪静态-无法读取配置文件,因为它超过了最大文件大小的解决办法

一直都在使用微软URLRewriter,具体的使用方法我就不多说了,网上文章很多。 但最近遇到一个问题,就是当web.config文件里面设置伪静态规则过多,大于2M的时候,就报错:无法读取配置文件,因为它超过…

java定义list_我的Java Web之路59 - Java中的泛型

本系列文章旨在记录和总结自己在Java Web开发之路上的知识点、经验、问题和思考,希望能帮助更多(Java)码农和想成为(Java)码农的人。目录介绍再谈Java中的类型为什么需要泛型?Java中的泛型泛型类型泛型方法总结介绍还记得我在这篇文章(我的Java Web之路3…

通过更改透明度使图片为透明

使用AlphaBlend函数 函数功能 该函数用来显示具有指定透明度的图像。函数原型 AlphaBlend(HDC hdcDest,int nXOriginDest,int nYOriginDest,int nWidthDest,int hHeightDest,HDC hdcSrc,int nXOriginSrc,int nYOriginSrc,int nWidthSrc,int nHeightSrc,BLENDFUNCTION blendFunc…

(转)CocoaPods:管理Objective-c 程序中各种第三方开源库关联

在我们的iOS程序中,经常会用到多个第三方的开源库,通常做法是去下载最新版本的开源库,然后拖拽到工程中。 但是,第三方开源库的数量一旦比较多,版本的管理就非常的麻烦。有没有什么办法可以简化对第三方库的管理呢&…