[
https://issues.apache.org/jira/browse/FELIX-3624?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=13491834#comment-13491834
]
Jarek Gawor commented on FELIX-3624:
------------------------------------
I think there might be a potential problem with the patch with the
searchResources(Requirement, Set) function. The function is supposed to search
for matching resources within a specified set of resources. With caching
enabled that means the m_capabilitiesCache will be checked first - a cache of
local and remote resources only. Once a matching resource is found in the cache
it will be checked against the specified set. That's good but there is at least
one case where the cache might not contain a resource in the specified set. For
example, the m_addedSet - which user can add resources to before resolve() is
called. So in this case, with caching, searchResources() would return null
instead of a matching resource from the m_addedSet.
> Performance tuning solution for BundleRepository/ResolverImpl
> -------------------------------------------------------------
>
> Key: FELIX-3624
> URL: https://issues.apache.org/jira/browse/FELIX-3624
> Project: Felix
> Issue Type: Improvement
> Components: Bundle Repository (OBR)
> Environment: Geronimo3 + BundleRepository 1.6.6
> Reporter: SheldonShao
> Priority: Critical
> Attachments: Felix_ResolverImpl_AfterTuning.png,
> Felix_ResolverImpl.png, repo_for_resolver_perf.xml, ResolverImpl.diff,
> ResolverImpl.java, ResolverImplTest.diff
>
>
> There are too many numebers of method calling about checking whether
> capabities are matched with requiment in ResolverImpl.searchResources.
> This is a performance issue of ResolverImpl.resolve.
> If it creates a capabity to resource+capabity mapping first. Then leverage
> this cache to do requirment matching. It will get better performance.
> Here is part of code. More details please check attachments.
> private final Map m_capabilitiesCache = new HashMap(8192);
> private String getKey(String filter, String prefix) {
> if (filter != null) {
> int index = filter.indexOf(prefix);
> if (index > 0) {
> int end = filter.indexOf(SUFFIX, index +
> prefix.length());
> if (end > index) {
> return filter.substring(index, end);
> }
> }
> }
> return null;
> }
> private String getKey(Requirement requirement) {
> String key = null;
> String name = requirement.getName();
> String filter = requirement.getFilter();
> if (Capability.BUNDLE.equals(name)) {
> key = getKey(filter, PREFIX_SYMBOLICNAME);
> } else if (Capability.PACKAGE.equals(name)) {
> key = getKey(filter, PREFIX_PACKAGE);
> } else if (Capability.SERVICE.equals(name)) {
> key = getKey(filter, PREFIX_SERVICE);
> } else if (Capability.FRAGMENT.equals(name)) {
> key = getKey(filter, PREFIX_HOST);
> } else {
> key = PREFIX_CAPABILITY + name;
> }
> return key;
> }
> private static final String PREFIX_SYMBOLICNAME = "symbolicname=";
> private static final String PREFIX_PACKAGE = "package=";
> private static final String PREFIX_SERVICE = "service=";
> private static final String PREFIX_HOST = "host=";
> private static final String PREFIX_CAPABILITY = "capability=";
> private static final char SUFFIX = ')';
> private void initCache(Capability[] capabilities, Resource resource) {
> Capability cap;
> Map properties;
> String name;
> for (int j = 0; j < capabilities.length; j++) {
> cap = capabilities[j];
> String key = null;
> properties = cap.getPropertiesAsMap();
> name = cap.getName();
> if (Capability.BUNDLE.equals(name)) {
> key = PREFIX_SYMBOLICNAME +
> properties.get("symbolicname");
> } else if (Capability.PACKAGE.equals(name)) {
> key = PREFIX_PACKAGE +
> properties.get("package");
> } else if (Capability.SERVICE.equals(name)) {
> key = PREFIX_SERVICE +
> properties.get("service");
> } else if (Capability.FRAGMENT.equals(name)) {
> key = PREFIX_HOST + properties.get("host");
> } else {
> key = PREFIX_CAPABILITY + name;
> }
> List caps = (List) m_capabilitiesCache.get(key);
> if (caps == null) {
> caps = new ArrayList(2);
> m_capabilitiesCache.put(key, caps);
> }
> caps.add(new ResourceCapabilityImpl(resource, cap));
> }
> }
> private void initCache(Resource[] locals) {
> Resource resource;
> for (int i = 0; i < locals.length; i++) {
> resource = locals[i];
> Capability[] capabilities = resource.getCapabilities();
> if (capabilities != null && capabilities.length > 0) {
> initCache(capabilities, resource);
> }
> }
> }
> /**
> * Searches for resources that do meet the given requirement
> *
> * @param req
> * the the requirement that must be satisfied by resources
> * @param resources
> * list of resources to look at
> * @return all resources meeting the given requirement
> */
> private List searchAllResources(Requirement req, Resource[] locals,
> Resource[] remotes) {
> String key = getKey(req);
> if (key != null) {
> List matchingCapabilities = new ArrayList();
> List capabilities = (List) m_capabilitiesCache.get(key);
> if (capabilities != null) {
> for (int capIdx = 0, size =
> capabilities.size(); capIdx < size; capIdx++) {
> checkInterrupt();
> ResourceCapabilityImpl capImpl =
> (ResourceCapabilityImpl) capabilities
> .get(capIdx);
> if
> (req.isSatisfied(capImpl.getCapability())) {
>
> matchingCapabilities.add(capImpl);
> }
> }
> }
> return matchingCapabilities;
> } else {
> List matchingCapabilities = searchResources(req,
> locals);
> matchingCapabilities.addAll(searchResources(req,
> remotes));
> return matchingCapabilities;
> }
> }
> public synchronized boolean resolve(int flags) {
> m_capabilitiesCache.clear();
>
> // Find resources
> Resource[] locals = getResources(true);
> //Create cache here
> initCache(locals);
> Resource[] remotes = getResources(false);
> initCache(remotes);
> .....
> }
>
> private Resource searchResources(Requirement req, Set resourceSet)
> private List searchResources(Requirement req,
> Resource[] resources)
>
> were also changed for leveraging this cache.
>
--
This message is automatically generated by JIRA.
If you think it was sent incorrectly, please contact your JIRA administrators
For more information on JIRA, see: http://www.atlassian.com/software/jira