Return-Path: X-Original-To: apmail-felix-dev-archive@www.apache.org Delivered-To: apmail-felix-dev-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id DFB0EDD41 for ; Thu, 9 Aug 2012 13:48:19 +0000 (UTC) Received: (qmail 88664 invoked by uid 500); 9 Aug 2012 13:48:19 -0000 Delivered-To: apmail-felix-dev-archive@felix.apache.org Received: (qmail 88617 invoked by uid 500); 9 Aug 2012 13:48:19 -0000 Mailing-List: contact dev-help@felix.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@felix.apache.org Delivered-To: mailing list dev@felix.apache.org Received: (qmail 88603 invoked by uid 99); 9 Aug 2012 13:48:19 -0000 Received: from issues-vm.apache.org (HELO issues-vm) (140.211.11.160) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 09 Aug 2012 13:48:19 +0000 Received: from isssues-vm.apache.org (localhost [127.0.0.1]) by issues-vm (Postfix) with ESMTP id 49364142819 for ; Thu, 9 Aug 2012 13:48:19 +0000 (UTC) Date: Thu, 9 Aug 2012 13:48:19 +0000 (UTC) From: "Richard S. Hall (JIRA)" To: dev@felix.apache.org Message-ID: <2051496054.1459.1344520099304.JavaMail.jiratomcat@issues-vm> In-Reply-To: <2115606841.241.1344493219131.JavaMail.jiratomcat@issues-vm> Subject: [jira] [Commented] (FELIX-3624) Performance tuning solution for BundleRepository/ResolverImpl MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 7bit X-JIRA-FingerPrint: 30527f35849b9dde25b450d4833f0394 [ https://issues.apache.org/jira/browse/FELIX-3624?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=13431806#comment-13431806 ] Richard S. Hall commented on FELIX-3624: ---------------------------------------- Thanks for looking into this. I am hopeful that eventually we will address some of these issues by re-implementing OBR using the new resolver subproject and then we could use the capability indexing approach of the framework to speed up matching too. > 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.png, Felix_ResolverImpl_AfterTuning.png, ResolverImpl.java > > > 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: https://issues.apache.org/jira/secure/ContactAdministrators!default.jspa For more information on JIRA, see: http://www.atlassian.com/software/jira