felix-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Richard S. Hall (JIRA)" <j...@apache.org>
Subject [jira] [Commented] (FELIX-3624) Performance tuning solution for BundleRepository/ResolverImpl
Date Thu, 09 Aug 2012 13:48:19 GMT

    [ 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

        

Mime
View raw message