Eclipse JDT的Index机制

Eclipse JDT的Index机制用于快速查找代码元素,如变量、方法等。Index保存在.metadata/.plugins/org.eclipse.jdt.core目录下,由IndexManager管理。Index的创建涉及多个类,如IndexManager、IndexRequest等,用于处理jar文件并生成保存在磁盘的索引文件,以提升代码搜索效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1. Index是什么?

JDT的Index目的是为了快速的查找变量,方法,构造函数,引用等位置的机制。

如下图,当我们在JDT中使用我框起来的功能时,都是Index机制在为我们服务。

2. Index保存在哪里?

Index的保存路径一般在:.metadata/.plugins/org.eclipse.jdt.core

以下是我的机器上的输出:

/home/test/runtime-EclipseApplication/.metadata/.plugins/org.eclipse.jdt.core
[test@ht191w org.eclipse.jdt.core]$ ls -alh
total 11M
drwxrwxr-x  2 test users 4.0K Nov 15 17:16 .
drwxrwxr-x 20 test users 4.0K Nov 15 12:48 ..
-rw-rw-r--  1 test users 169K Nov 15 17:16 1189544457.index
-rw-rw-r--  1 test users 270K Nov 15 17:16 1266648557.index
-rw-rw-r--  1 test users 9.4M Nov 15 17:16 1346760340.index
-rw-rw-r--  1 test users  91K Nov 15 17:16 1481681510.index
-rw-rw-r--  1 test users   25 Nov 15 17:01 1501317170.index
-rw-rw-r--  1 test users 174K Nov 15 17:16 1580850431.index
-rw-rw-r--  1 test users  387 Nov 15 17:16 2266944301.index
-rw-rw-r--  1 test users  38K Nov 15 17:16 2268464613.index
-rw-rw-r--  1 test users  90K Nov 15 17:16 3421611052.index
-rw-rw-r--  1 test users  53K Nov 15 17:16 4283481814.index
-rw-rw-r--  1 test users 4.2K Nov 15 17:16 680003802.index
-rw-rw-r--  1 test users  22K Nov 15 17:16 690271857.index
-rw-rw-r--  1 test users  870 Nov 15 18:19 externalLibsTimeStamps
-rw-rw-r--  1 test users    4 Nov 15 18:19 invalidArchivesCache
-rw-rw-r--  1 test users    4 Nov 15 10:36 javaLikeNames.txt
-rw-rw-r--  1 test users  782 Nov 15 18:19 nonChainingJarsCache
-rw-rw-r--  1 test users  304 Nov 15 17:16 savedIndexNames.txt
-rw-rw-r--  1 test users  21K Nov 15 18:19 variablesAndContainers.dat

3. Index机制的基本描述

3.1 Index机制的参与类

org.eclipse.jdt.internal.core.search.indexing.IndexManager 用来管理Index,创建,删除,重建,查找等操作

org.eclipse.jdt.internal.core.index.Index 用来操作Index,它包含了

org.eclipse.jdt.internal.core.index.MemoryIndex 和org.eclipse.jdt.internal.core.index.DiskIndex

org.eclipse.jdt.internal.core.search.indexing.IndexRequest 用来给IndexManager发送请求来建立Index

下面是它的子类:


org.eclipse.jdt.internal.core.search.processing.IJob是IndexManager处理请求的所有基类:


org.eclipse.jdt.internal.core.search.PatternSearchJob用来处理所有查找的对象,它的一个注意成员就是SearchPattern,以下是它们继承等级:


3.2 IndexManager的创建

当jdt.core plugins启动时, org.eclipse.jdt.core.JavaCore将创建IndexManager类,来处理对Index的各种请求

如下图高亮的就是Java Indexing线程:


3.3 Index的建立和使用

通过org.eclipse.jdt.internal.core.search.indexing.IndexManager的

public synchronized IndexLocation computeIndexLocation(IPath containerPath) {
    IndexLocation indexLocation = (IndexLocation) this.indexLocations.get(containerPath);
    if (indexLocation == null) {
        String pathString = containerPath.toOSString();
        CRC32 checksumCalculator = new CRC32();
        checksumCalculator.update(pathString.getBytes());
        String fileName = Long.toString(checksumCalculator.getValue()) + ".index"; //$NON-NLS-1$
        if (VERBOSE)
            Util.verbose("-> index name for " + pathString + " is " + fileName); //$NON-NLS-1$ //$NON-NLS-2$
        // to share the indexLocation between the indexLocations and indexStates tables, get the key from the indexStates table
        indexLocation = (IndexLocation) getIndexStates().getKey(new FileIndexLocation(new File(getSavedIndexesDirectory(), fileName)));
        this.indexLocations.put(containerPath, indexLocation);
    }
    return indexLocation;
}

来计算index文件的名字
然后检查对应的index文件是否存在,如果存在,则直接使用,如果不存在的话,通过
private void rebuildIndex(IndexLocation indexLocation, IPath containerPath) {
    Object target = JavaModel.getTarget(containerPath, true);
    if (target == null) return;

    if (VERBOSE)
        Util.verbose("-> request to rebuild index: "+indexLocation+" path: "+containerPath); //$NON-NLS-1$ //$NON-NLS-2$

    updateIndexState(indexLocation, REBUILDING_STATE);
    IndexRequest request = null;
    if (target instanceof IProject) {
        IProject p = (IProject) target;
        if (JavaProject.hasJavaNature(p))
            request = new IndexAllProject(p, this);
    } else if (target instanceof IFolder) {
        request = new IndexBinaryFolder((IFolder) target, this);
    } else if (target instanceof IFile) {
        request = new AddJarFileToIndex((IFile) target, null, this);
    } else if (target instanceof File) {
        request = new AddJarFileToIndex(containerPath, null, this);
    }
    if (request != null)
        request(request);
}

发送IndexRequest来重建index。 不管是Java工程还是Jar文件,最终都分为两类,一类是source文件,一类是class文件,如下图:

IndexManager来处理收到的IndexRequest来生成Index。

比如下面的堆栈,是处理jar文件并生成Index的调用:

以下是其中一次调用所传递的参数:

category [t, y, p, e, D, e, c, l]
key [a, c, c, e, s, s, i, b, i, l, i, t, y, /, c, o, m, ., s, u, n, ., a, c, c, e, s, s, i, b, i, l, i, t, y, ., i, n, t, e, r, n, a, l, ., r, e, s, o, u, r, c, e, s, /, /, 1,
documentName com/sun/accessibility/internal/resources/accessibility.class


生成的Index最后会保存道磁盘上,便于以后使用,不需要再次创建,Index文件的header当前是INDEX VERSION 1.126。

以下是DiskIndex中重要的两个变量的Variable截图:

如果我们收到org.eclipse.jdt.core.search.SearchRequestor,我们只需要根据对应的catogory读取文件中对应的位置(根据categoryOffsets和categoryEnds),

然后就可以快速的查找到对应请求的关系,比如变量a的调用的地方,方法b的声明的地方,方法c的父类声明在哪里等。


下面是IndexManager对一个Java工程进行完Index后,所有的Index:

file:/home/jialiang/runtime-EclipseApplication/.metadata/.plugins/org.eclipse.jdt.core/690271857.index -> Index for /usr/lib/jvm/java-1.6.0-openjdk-1.6.0.0.x86_64/jre/lib/ext/localedata.jar
file:/home/jialiang/runtime-EclipseApplication/.metadata/.plugins/org.eclipse.jdt.core/680003802.index -> Index for /usr/lib/jvm/java-1.6.0-openjdk-1.6.0.0.x86_64/jre/lib/ext/dnsns.jar
file:/home/test/runtime-EclipseApplication/.metadata/.plugins/org.eclipse.jdt.core/3421611052.index -> Index for /usr/lib/jvm/java-1.6.0-openjdk-1.6.0.0.x86_64/jre/lib/ext/sunpkcs11.jar
file:/home/jialiang/runtime-EclipseApplication/.metadata/.plugins/org.eclipse.jdt.core/1580850431.index -> Index for /usr/lib/jvm/java-1.6.0-openjdk-1.6.0.0.x86_64/jre/lib/charsets.jar
file:/home/jialiang/runtime-EclipseApplication/.metadata/.plugins/org.eclipse.jdt.core/1346760340.index -> Index for /usr/lib/jvm/java-1.6.0-openjdk-1.6.0.0.x86_64/jre/lib/rt.jar
file:/home/jialiang/runtime-EclipseApplication/.metadata/.plugins/org.eclipse.jdt.core/2268464613.index -> Index for /usr/lib/jvm/java-1.6.0-openjdk-1.6.0.0.x86_64/jre/lib/jce.jar
file:/home/jialiang/runtime-EclipseApplication/.metadata/.plugins/org.eclipse.jdt.core/4283481814.index -> Index for /usr/lib/jvm/java-1.6.0-openjdk-1.6.0.0.x86_64/jre/lib/ext/sunjce_provider.jar
file:/home/jialiang/runtime-EclipseApplication/.metadata/.plugins/org.eclipse.jdt.core/1481681510.index -> Index for /usr/lib/jvm/java-1.6.0-openjdk-1.6.0.0.x86_64/jre/lib/jsse.jar
file:/home/jialiang/runtime-EclipseApplication/.metadata/.plugins/org.eclipse.jdt.core/1266648557.index -> Index for /usr/lib/jvm/java-1.6.0-openjdk-1.6.0.0.x86_64/jre/lib/rhino.jar
file:/home/jialiang/runtime-EclipseApplication/.metadata/.plugins/org.eclipse.jdt.core/1189544457.index -> Index for /usr/lib/jvm/java-1.6.0-openjdk-1.6.0.0.x86_64/jre/lib/ext/gnome-java-bridge.jar
file:/home/jialiang/runtime-EclipseApplication/.metadata/.plugins/org.eclipse.jdt.core/1501317170.index -> Index for /usr/lib/jvm/java-1.6.0-openjdk-1.6.0.0.x86_64/jre/lib/resources.jar
file:/home/jialiang/runtime-EclipseApplication/.metadata/.plugins/org.eclipse.jdt.core/2266944301.index -> Index for /dd

Index的使用都是通过调用IndexManager的performConcurrentJob来完成的,以下是它的调用堆栈:






首先了解一下flexBuilder FlexBuilder 2.0 是建立在 eclipse 3.1基础上的 FlexBuilder 3.2.1 是建立在eclipse 3.2.1基础上的 所以要想支持vss 首先要准备eclipse 3.1 或者 eclipse3.2.1 就看你用什么版本的flexbuilder FlexBuilder 3使用 vss1.6.1; FlashBuilder 4使用 vss 1.6.2; 1. 下下载一个vss插件 最新版本是1.6.2 下载地址:http://sourceforge.net/projects/vssplugin/ (或者http://download.csdn.net/detail/ch_kexin/4925652) 放入 flexbuilder 目录的plugin 目录下 打开flexbuilder 很多人都会发现不能用 当然这也是让很多人忘而却步的地方 2. 为什么不能用? 原因是flexbuilder中 精简了eclipse 中的一些组建 ,vss插件又需要,怎么办? 刚准备的eclipse 就发挥了用处 下载一个eclipse (请下载对应的版本) 然后解开 将eclipse 的plugin 目录下的 org.eclipse.jdt.* 的目录和文件 全部拷贝到 flexbuilder 的plugin (若为myEclipse则是将myEclipseeclipse\plugins) flashbuilder也一样 ----下面是在FlexBuilder中配置VSS ------- 1. 首先绑定项目到VSS。就算打开的项目是从VSS里获取的,第一次打开也需要手动绑定。选中图中最后一个菜单中的选项:Share Project进入新界面后,选中VSS Configuration Wizard进入如下界面。 2. 填上客户端用户名、密码、服务器端VSS目录、项目目录、项目在VSS里的目录。 VSS Repository supports multiple checkouts.不选,此项是VSS支持多人同时签出。根据实际情况决定是否选中。 3.单击Finish。配置VSS完毕。 4.配置完毕。 VSS配置完成后。项目并未与VSS有任何关联,此时需要 Update State来关联到VSS。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值