今天分析一下eclipse jface 下document 下copyOnwriteTextStore 类的实现。
eclipse 是一个非常受欢迎的ide 工具,既然是ide,强大的文本编辑功能必然是必备功能之一。那么要很好的操纵文本,良好的定位文本和替换特定文本便是文本编辑的基础。
今天来分析一下document 类下的一个实现快速替换文本的类。copyOnwriteTextStore,对java 并发类熟悉的人,听名字可能觉得是不是和CopyOnWriteArrayList 什么的有关系,其实和并发没有什么关系,只是内部有两个工作类,只读的时候,通过StringTextStore来操作文本。当有replace 发生,则换到modifiableTextStore类来实现。document 默认用的是GapTextStore来工作。
GapTextStore 为了提高性能,不在每次replace是都开辟内存,在实现时加了一个冗余gap。好那既然是通过冗余gap来避免不必要的重复开辟内存。实现gap及时算法的关键。那我们先提出几个关于gap问题,之后再给出代码是如何解决这些问题的。1 gap 什么时候产生?2,gap 有范围吗?3 gap 在什么位置产生。知道这三个问题的答案,这个实现也就知道了。
第一,当replace 发生gap 产生,分两种情况一个是gap 加文本长度够且小于阈值的情况。一种是不够或大于gap大于阈值的情况。这两种情况是不同的。
第二,replace 计算新的长度差,新的大于旧的或新的小于旧的,但差值大于阈值,进入第二种情况,否则进入第一种。第二种情况下,先计算新长度,之后乘以一个大于1的长度变化因子获得长度,gap 值为新长度减掉文本长度,如果大于或小于gap上下线,gap自动设为对应值,新长度响应改变。
第三,gap的位置不是在头也不是在尾部,而是在replace 目标替换掉就文本后的后面,这样好处是在第一种情况下文本移动要简单。
一下为调整代码
private void adjustGap(int offset, int remove, int add) { final int oldGapSize= gapSize(); final int newGapSize= oldGapSize - add + remove; final boolean reuseArray= 0 <= newGapSize && newGapSize <= fThreshold; final int newGapStart= offset + add; final int newGapEnd; if (reuseArray) newGapEnd= moveGap(offset, remove, oldGapSize, newGapSize, newGapStart); else newGapEnd= reallocate(offset, remove, oldGapSize, newGapSize, newGapStart); fGapStart= newGapStart; fGapEnd= newGapEnd; }
第二种情况代码:
private int reallocate(int offset, int remove, final int oldGapSize, int newGapSize, final int newGapStart) { // the new content length (without any gap) final int newLength= fContent.length - newGapSize; // the new array size based on the gap factor int newArraySize= (int) (newLength * fSizeMultiplier); newGapSize= newArraySize - newLength; // bound the gap size within min/max if (newGapSize < fMinGapSize) { newGapSize= fMinGapSize; newArraySize= newLength + newGapSize; } else if (newGapSize > fMaxGapSize) { newGapSize= fMaxGapSize; newArraySize= newLength + newGapSize; } // the upper threshold is always twice the gapsize fThreshold= newGapSize * 2; final char[] newContent= allocate(newArraySize); final int newGapEnd= newGapStart + newGapSize; /* * Re-allocation: The old content can be copied in at most 3 operations to the newly allocated * array. Either one of change offset and the gap may come first. * - unchanged area before the change offset / gap * - area between the change offset and the gap (either one may be first) * - rest area after the change offset / after the gap */ if (offset < fGapStart) { // change comes before gap arrayCopy(0, newContent, 0, offset); int afterRemove= offset + remove; if (afterRemove < fGapStart) { // removal is completely before the gap final int betweenSize= fGapStart - afterRemove; arrayCopy(afterRemove, newContent, newGapEnd, betweenSize); final int restSize= fContent.length - fGapEnd; arrayCopy(fGapEnd, newContent, newGapEnd + betweenSize, restSize); } else { // removal encompasses the gap afterRemove += oldGapSize; final int restSize= fContent.length - afterRemove; arrayCopy(afterRemove, newContent, newGapEnd, restSize); } } else { // gap comes before change arrayCopy(0, newContent, 0, fGapStart); final int offsetShifted= offset + oldGapSize; final int betweenSize= offsetShifted - fGapEnd; arrayCopy(fGapEnd, newContent, fGapStart, betweenSize); final int afterRemove= offsetShifted + remove; final int restSize= fContent.length - afterRemove; arrayCopy(afterRemove, newContent, newGapEnd, restSize); } fContent= newContent; return newGapEnd; }
第一种情况代码:
private int moveGap(int offset, int remove, int oldGapSize, int newGapSize, int newGapStart) { /* * No re-allocation necessary. The area between the change offset and gap can be copied * in at most one operation. Don't copy parts that will be overwritten anyway. */ final int newGapEnd= newGapStart + newGapSize; if (offset < fGapStart) { int afterRemove= offset + remove; if (afterRemove < fGapStart) { final int betweenSize= fGapStart - afterRemove; arrayCopy(afterRemove, fContent, newGapEnd, betweenSize); } // otherwise, only the gap gets enlarged } else { final int offsetShifted= offset + oldGapSize; final int betweenSize= offsetShifted - fGapEnd; // in the typing case, betweenSize is 0 arrayCopy(fGapEnd, fContent, fGapStart, betweenSize); } return newGapEnd; }
相关推荐
因此,Eclipse的代码行数统计插件只是开发辅助工具的一种,它与其他静态代码分析工具、代码格式化器和覆盖率测试工具一起,构成了提高代码质量和效率的完整生态系统。通过合理利用这些工具,开发者可以更有效地管理...
"统计代码行数的Eclipse插件"就是这样一个工具,它能够帮助开发者快速地分析和度量他们的代码库,包括注释和实际可执行代码的数量。 这个插件设计精良,经过全面测试,确保了统计结果的准确性。无论是整个工程目录...
eclipse 代码规范模板定义 eclipse 代码规范模板定义 eclipse 代码规范模板定义
1. `winit-code-format.xml`:这是一个Eclipse的代码格式化配置文件。它定义了代码如何被自动格式化,包括缩进、空格、括号对齐、换行策略等。开发者可以设置自己的喜好,如使用 tabs 还是 spaces,以及每行的最大...
CheckStyle是一款静态代码分析工具,它按照预定义的编码规范检查源代码,确保代码的一致性和可读性。通过在Eclipse中安装CheckStyle插件,开发者可以实时地在编辑器中看到违反编码规范的地方,并及时进行修复。例如...
Eclipse代码生成器插件开发 在本节中,我们将探讨Eclipse代码生成器插件开发的相关知识点。 一、插件开发基本概念 在Eclipse中,插件是一种可以扩展Eclipse功能的组件。插件可以提供新的功能、视图、编辑器等。要...
在软件开发过程中,准确地统计代码量是一项重要的任务,它有助于评估项目的规模,跟踪开发进度,以及进行代码质量分析。Eclipse作为一个强大的Java集成开发环境(IDE),提供了丰富的插件支持,其中包括用于统计代码...
1. **自定义折叠点**:允许用户根据个人需求定义折叠区域,比如类定义、方法、循环、注释等,使得代码视图更加简洁。 2. **快捷操作**:通过快捷键或者右键菜单,用户可以快速折叠或展开选定的代码块,提高了代码...
1. **解压下载的压缩包**:首先,你需要将"eclipse代码着色插件.rar"解压到一个文件夹。 2. **启动Eclipse**:打开你的Eclipse IDE。 3. **访问Eclipse Marketplace**:通过菜单栏选择“帮助”(Help) -> "Eclipse ...
“eclipse 代码格式化”是Eclipse IDE内置的一个重要特性,它可以自动调整代码的缩进、空格、换行等格式问题。当你编写或导入代码后,通过使用这个功能,可以将代码按照预设的规范进行美化,使代码看起来更加整洁...
5. **代码格式化**:Eclipse的“Source”菜单下的“Format”功能可以一键按照预设的代码风格格式化代码,提高代码整洁度。 6. **编码约定**:包括类型转换的处理、异常处理策略、避免魔法数字等,这些都是团队内部...
eclipse配置代码颜色 Eclipse 是一款功能强大且广泛使用的集成开发环境(IDE)。它提供了丰富的功能和插件来提高开发效率。以下是 Eclipse 配置代码颜色和快捷键的使用方法,以提高工作效率。 一、Eclipse 配置...
1. **代码行数统计**:它能统计源代码文件中的总行数,包括空行、注释行和实际的代码行,这对于理解项目规模非常有帮助。 2. **代码复杂度分析**:插件可能还支持计算代码的Cyclomatic Complexity,这是一个衡量...
Jocky提供了对IDE Eclipse的支持,同时,也支持在Ant中使用(事实上,在Eclipse中,也是先生成一个ant文件,然后再编译). 是挺好用, 编译后的代码大部分反编译出来只有 JVM 指令! 的确是保护系统核心的利器! 支持 ...
1. **代码缩进**:在Eclipse中,可以设置代码的缩进方式,通常选择空格而不是制表符,以确保在不同的编辑器中显示的一致性。默认情况下,Java代码通常使用4个空格作为缩进单位。 2. **行宽限制**:为了保持代码的...
android官方eclipse代码规范
Eclipse代码格式模板,Ctrl+Shift+F格式化代码,有利于团队代码格式规范。
Eclipse是一款广泛使用的Java集成开发环境(IDE),它提供了丰富的功能来帮助开发者高效地编写和管理代码。在软件开发过程中,代码折叠功能是一项非常实用的工具,它允许开发者隐藏或展开代码块,以便于集中精力在...
Eclipse代码格式化模版,可以参照我的博客进行设置。http://blog.csdn.net/u010028869
eclipse中可以类似idea那样ctrl+shift+enter自动补全末尾分号,以及换号功能的插件。此插件原来可以在eclipse市场中添加,不过现在页面丢失了,此插件为之前下载保存,下载下来直接复制到eclipse的plugins地下即可,...