`
zhouxy1123
  • 浏览: 6226 次
文章分类
社区版块
存档分类
最新评论

eclipse 代码分析(1)CopyOnWriteTextStore

阅读更多

今天分析一下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 代码规范模板定义

    eclipse 代码规范模板定义 eclipse 代码规范模板定义 eclipse 代码规范模板定义

    eclipse代码规范文件

    1. `winit-code-format.xml`:这是一个Eclipse的代码格式化配置文件。它定义了代码如何被自动格式化,包括缩进、空格、括号对齐、换行策略等。开发者可以设置自己的喜好,如使用 tabs 还是 spaces,以及每行的最大...

    Eclipse 代码质量检测评估插件合集

    CheckStyle是一款静态代码分析工具,它按照预定义的编码规范检查源代码,确保代码的一致性和可读性。通过在Eclipse中安装CheckStyle插件,开发者可以实时地在编辑器中看到违反编码规范的地方,并及时进行修复。例如...

    Eclipse代码生成器插件开发

    Eclipse代码生成器插件开发 在本节中,我们将探讨Eclipse代码生成器插件开发的相关知识点。 一、插件开发基本概念 在Eclipse中,插件是一种可以扩展Eclipse功能的组件。插件可以提供新的功能、视图、编辑器等。要...

    Eclipse中用于统计代码量的插件

    在软件开发过程中,准确地统计代码量是一项重要的任务,它有助于评估项目的规模,跟踪开发进度,以及进行代码质量分析。Eclipse作为一个强大的Java集成开发环境(IDE),提供了丰富的插件支持,其中包括用于统计代码...

    eclipse代码折叠插件

    1. **自定义折叠点**:允许用户根据个人需求定义折叠区域,比如类定义、方法、循环、注释等,使得代码视图更加简洁。 2. **快捷操作**:通过快捷键或者右键菜单,用户可以快速折叠或展开选定的代码块,提高了代码...

    eclipse代码着色插件.rar

    1. **解压下载的压缩包**:首先,你需要将"eclipse代码着色插件.rar"解压到一个文件夹。 2. **启动Eclipse**:打开你的Eclipse IDE。 3. **访问Eclipse Marketplace**:通过菜单栏选择“帮助”(Help) -&gt; "Eclipse ...

    eclipse 代码格式化

    “eclipse 代码格式化”是Eclipse IDE内置的一个重要特性,它可以自动调整代码的缩进、空格、换行等格式问题。当你编写或导入代码后,通过使用这个功能,可以将代码按照预设的规范进行美化,使代码看起来更加整洁...

    eclipse优秀代码风格

    5. **代码格式化**:Eclipse的“Source”菜单下的“Format”功能可以一键按照预设的代码风格格式化代码,提高代码整洁度。 6. **编码约定**:包括类型转换的处理、异常处理策略、避免魔法数字等,这些都是团队内部...

    eclipse配置代码颜色

    eclipse配置代码颜色 Eclipse 是一款功能强大且广泛使用的集成开发环境(IDE)。它提供了丰富的功能和插件来提高开发效率。以下是 Eclipse 配置代码颜色和快捷键的使用方法,以提高工作效率。 一、Eclipse 配置...

    eclipse统计代码工具

    1. **代码行数统计**:它能统计源代码文件中的总行数,包括空行、注释行和实际的代码行,这对于理解项目规模非常有帮助。 2. **代码复杂度分析**:插件可能还支持计算代码的Cyclomatic Complexity,这是一个衡量...

    Eclipse代码混淆插件通用JDK

    Jocky提供了对IDE Eclipse的支持,同时,也支持在Ant中使用(事实上,在Eclipse中,也是先生成一个ant文件,然后再编译). 是挺好用, 编译后的代码大部分反编译出来只有 JVM 指令! 的确是保护系统核心的利器! 支持 ...

    Eclipse代码格式配置规范

    1. **代码缩进**:在Eclipse中,可以设置代码的缩进方式,通常选择空格而不是制表符,以确保在不同的编辑器中显示的一致性。默认情况下,Java代码通常使用4个空格作为缩进单位。 2. **行宽限制**:为了保持代码的...

    android官方eclipse代码规范

    android官方eclipse代码规范

    Eclipse代码格式模板

    Eclipse代码格式模板,Ctrl+Shift+F格式化代码,有利于团队代码格式规范。

    Eclipse实现代码折叠功能插件,基于com.cb.eclipse.folding-1.0.6.jar

    Eclipse是一款广泛使用的Java集成开发环境(IDE),它提供了丰富的功能来帮助开发者高效地编写和管理代码。在软件开发过程中,代码折叠功能是一项非常实用的工具,它允许开发者隐藏或展开代码块,以便于集中精力在...

    Eclipse代码格式化模版

    Eclipse代码格式化模版,可以参照我的博客进行设置。http://blog.csdn.net/u010028869

    eclipse代码自动补全插件

    eclipse中可以类似idea那样ctrl+shift+enter自动补全末尾分号,以及换号功能的插件。此插件原来可以在eclipse市场中添加,不过现在页面丢失了,此插件为之前下载保存,下载下来直接复制到eclipse的plugins地下即可,...

Global site tag (gtag.js) - Google Analytics