索引和PSI Stubs

走着路睡觉大约 4 分钟

索引

通过索引可以快速查找元素,例如:在代码库中,查找包含某个单词或某个方法的文件。插件开发者可以使用IDE已有的索引来构建和使用自己的索引。

有以下2种索引:

  • 文件索引 :基于文件内容构建的索引。通过该索引可以直接搜索到符合指定条件的文件

  • Stud索引 :基于序列化Stub trees 构建。 Stub tree 是PSI tree 的子集,只包含PSI tree中外部可见的声明,以二进制格式存储。该索引可以搜索符合指定条件的PSI元素集。

提示

PSI tree: PSI树,例如在java类中,java类会被解构为一个一个的PsiElement(PSI元素),所有的PsiElement构建为一个PSI树,可以参考文档 PSI元素

提示

可以使用 Index Vieweropen in new window 插件查看索引的内容和属性。

Dumb mode

索引在后台进程中进行构建,在构建索引的过程中,DumbServiceopen in new window 限制了 只能使用 文本编辑或版本控制等不需要使用索引的功能 ,如果调用了需要使用索引的功能,会抛出 IndexNotReadyExceptionopen in new window 异常。

通过DumbService 可以获取当前项目处于 dumb模式(该模式下不能访问索引)还是 smart模式(该模式下,索引构建完成,可以使用索引),也可以等待项目处于smart模式时再执行操作。

    //判断项目处于什么模式下
    // dumb模式(该模式下不能访问索引)
    //  smart模式(该模式下,索引构建完成,可以使用索引)
    DumbService.getInstance(project).isDumb();
    DumbService.isDumb(project);
    
    //等待项目处于 smart模式 时,再执行业务操作
    DumbService.getInstance(project).runWhenSmart(()->{//业务逻辑});

Gists

有时候会碰到以下情况:

  • 不需要使用文件索引,只需要计算文件内容的相关数据,并将数据缓存到硬盘上

  • 不需要在索引构建期间执行计算(例如:它会拖慢索引的构建,或者只有一小部分文件曾经需要这些计算数据)

  • 可以根据请求延迟重新计算数据,而不会造成明显的性能损失。

大部分情况下可以使用 文件索引 ,但是通过 gists的API 可以延迟计算,并缓存到硬盘上, 可以参考 VirtualFileGistopen in new windowPsiFileGistopen in new window 的文档。

示例:

提高索引性能

性能指标

在2020.2及以后的版本中,索引的性能指标以json格式存储在了沙盒中的logs文件夹中,从2021.1版本开始,以HTML格式存储了另外的一些指标,参考下图:

沙盒路径查看文档:插件开发项目配置

避免使用AST

如果可能,尽量使用词法分析器信息而不是解析树。 如果不可能,请使用不会占用大量内存的经量级AST(LighterAST) ,这样可以提升遍历速度。可以通过将传过来的 FileContent参数 转换为 PsiDependentFileContent 然后调用 getLighterAST() 来获取 LighterAST,使用 LighterASTNodeVisitoropen in new windowLightTreeUtilopen in new window 来遍历自己需要用到的节点,

继承 LightStubBuilderopen in new window 来实现轻量级 Stub 索引

If a custom language contains lazy-parseable elements that never or rarely contain any stubs, consider implementing StubBuilder.skipChildProcessingWhenBuildingStubs()open in new window (preferably using Lexer/node text).

考虑使用 NanoXmlUtilopen in new window 来索引 xml 文件

预创建Stubs

如果你使用的编程语言有大量的对所有用户都一样的组件库,你可以注册 PrebuiltStubsProvideropen in new window 扩展 来预创建Stubs索引,避免每次安装都需要构建Stubs索引。

上次编辑于:
贡献者: zhaojingbo
Loading...