felix-dev mailing list archives

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

     [ https://issues.apache.org/jira/browse/FELIX-3624?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]

SheldonShao updated FELIX-3624:
-------------------------------

    Description: 
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.


              

  was:
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.

    
> 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
>         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