[ 
https://issues.apache.org/jira/browse/FELIX-3624?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=13431757#comment-13431757
 ] 

SheldonShao commented on FELIX-3624:
------------------------------------

I am new for this. I will check "Grant license to ASF for inclusion in ASF 
works" later.
And also I am going to refine the code and provide what I changed and test 
result.
Thanks guys.
                
> 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

        

Reply via email to