IResourceScopeCache 用于避免昂贵的范围计算
IResourceScopeCache for Avoid expensive scope calculation
我遇到了与 is this link
描述的相同问题
我想在我实现的 getScope 函数中使用 IResourceScopeCache,但我不知道该怎么做。没有找到任何对我有帮助的东西。
我有这个文件:MyDslScopeProvider.xtend,我在那里覆盖了 getScope()。
我怎样才能在那里使用缓存?
override def IScope getScope(EObject context, EReference reference) {
if (reference == SpectraPackage.Literals.TEMPORAL_PRIMARY_EXPR__POINTER) {
val contextDecl = EcoreUtil2.getContainerOfType(context, Decl);
val root = EcoreUtil2.getContainerOfType(context, Model)
val elements = root.elements
val List<EObject> EObjectsInScope = newArrayList
if (contextDecl instanceof Predicate) {
val pred = contextDecl as Predicate
EObjectsInScope.addAll(pred.params.params)
EObjectsInScope.addAll(consts)
EObjectsInScope.addAll(varDecls)
return Scopes.scopeFor(EObjectsInScope)
}
else if (contextDecl instanceof Pattern) {
val patt = contextDecl as Pattern
EObjectsInScope.addAll(patt.varDeclList)
EObjectsInScope.addAll(patt.params.params)
return Scopes.scopeFor(EObjectsInScope)
}
else{
//geting all the elements I need.(didn't added it here because it's a lot of code)
return Scopes.scopeFor(EObjectsInScope)
}
return Scopes.scopeFor(EObjectsInScope)
}
}
return super.getScope(context, reference);
}
我有 3 个不同的案例。
接口 IResourceScopeCache
允许使用您选择的键将为给定资源计算的值存储在地图中。
它有两种方法:<T> T get(Object key, Resource res, Provider<T> provider)
和 void clear(Resource res)
。
get
检查是否已经为给定的键和资源计算了一个值。如果它已经存在,则返回缓存的值,否则使用提供程序计算该值,然后将其存储在缓存中以供后续重用。 clear
删除给定键的计算值(如果存在)。
您必须注入 IResourceScopeCache 类型的字段并考虑从上下文 EObject 生成缓存键的方案:
您必须确保无论何时检索给定缓存键和资源的值,如果实际执行了缓存计算 (provider
) 的结果将是相同的,因此它是正确地重新使用缓存的值。特别是,您必须确保计算结果仅取决于您传递给 get
方法的资源的内容,因为缓存的值仅在该资源更改时才重新计算。
但是,在执行此操作时,您必须确保在计算结果必然相同的地方没有不必要的不同缓存键,以最大限度地重复使用并最大限度地减少重复计算。
根据您论坛中的代码示例 post 我看不到很好的缓存候选者。但也许有一些我从这个例子中看不到的东西。
局部变量不是缓存的最佳选择,原因至少有两个:
- 块和语句没有可用于缓存键的名称。
- 即使您这样做,局部变量也只能在声明后在 expressions/statements 中使用,因此每个语句可能有一组不同的可用局部变量。这使得通过合理的努力实现合理的重用变得更加困难。
如果您无论如何都想这样做,也许您可以使用语句在包含层次结构中的位置来计算缓存键,类似于代理 URI 片段(参见 org.eclipse.xtext.linking.lazy.LazyURIEncoder),但不使用字符串,并且重新使用前面语句的计算值(以及块的第一条语句的包含块)。
我遇到了与 is this link
描述的相同问题我想在我实现的 getScope 函数中使用 IResourceScopeCache,但我不知道该怎么做。没有找到任何对我有帮助的东西。 我有这个文件:MyDslScopeProvider.xtend,我在那里覆盖了 getScope()。 我怎样才能在那里使用缓存?
override def IScope getScope(EObject context, EReference reference) {
if (reference == SpectraPackage.Literals.TEMPORAL_PRIMARY_EXPR__POINTER) {
val contextDecl = EcoreUtil2.getContainerOfType(context, Decl);
val root = EcoreUtil2.getContainerOfType(context, Model)
val elements = root.elements
val List<EObject> EObjectsInScope = newArrayList
if (contextDecl instanceof Predicate) {
val pred = contextDecl as Predicate
EObjectsInScope.addAll(pred.params.params)
EObjectsInScope.addAll(consts)
EObjectsInScope.addAll(varDecls)
return Scopes.scopeFor(EObjectsInScope)
}
else if (contextDecl instanceof Pattern) {
val patt = contextDecl as Pattern
EObjectsInScope.addAll(patt.varDeclList)
EObjectsInScope.addAll(patt.params.params)
return Scopes.scopeFor(EObjectsInScope)
}
else{
//geting all the elements I need.(didn't added it here because it's a lot of code)
return Scopes.scopeFor(EObjectsInScope)
}
return Scopes.scopeFor(EObjectsInScope)
}
}
return super.getScope(context, reference);
}
我有 3 个不同的案例。
接口 IResourceScopeCache
允许使用您选择的键将为给定资源计算的值存储在地图中。
它有两种方法:<T> T get(Object key, Resource res, Provider<T> provider)
和 void clear(Resource res)
。
get
检查是否已经为给定的键和资源计算了一个值。如果它已经存在,则返回缓存的值,否则使用提供程序计算该值,然后将其存储在缓存中以供后续重用。 clear
删除给定键的计算值(如果存在)。
您必须注入 IResourceScopeCache 类型的字段并考虑从上下文 EObject 生成缓存键的方案:
您必须确保无论何时检索给定缓存键和资源的值,如果实际执行了缓存计算 (provider
) 的结果将是相同的,因此它是正确地重新使用缓存的值。特别是,您必须确保计算结果仅取决于您传递给 get
方法的资源的内容,因为缓存的值仅在该资源更改时才重新计算。
但是,在执行此操作时,您必须确保在计算结果必然相同的地方没有不必要的不同缓存键,以最大限度地重复使用并最大限度地减少重复计算。
根据您论坛中的代码示例 post 我看不到很好的缓存候选者。但也许有一些我从这个例子中看不到的东西。
局部变量不是缓存的最佳选择,原因至少有两个:
- 块和语句没有可用于缓存键的名称。
- 即使您这样做,局部变量也只能在声明后在 expressions/statements 中使用,因此每个语句可能有一组不同的可用局部变量。这使得通过合理的努力实现合理的重用变得更加困难。
如果您无论如何都想这样做,也许您可以使用语句在包含层次结构中的位置来计算缓存键,类似于代理 URI 片段(参见 org.eclipse.xtext.linking.lazy.LazyURIEncoder),但不使用字符串,并且重新使用前面语句的计算值(以及块的第一条语句的包含块)。