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

Florian Müller resolved CMIS-896.
---------------------------------
       Resolution: Fixed
    Fix Version/s: OpenCMIS 0.13.0

The improvement covers this specific case:
A server response contains at least one object and the client requested the 
cmis:objectId property but not the cmis:objectTypeId property and/or the object 
has secondary type properties that the client also requested. Although, queries 
are the mostly likely candidates for this scenario, other operations are also 
affected (getObject(), getChildren(), etc.).

Two things have changed:
- getObject() is not called for each returned object, but only if it is 
necessary. That is, it is only called if a property should be returned and its 
property definition has not been fetched before for this response. That reduces 
the number of getObject() calls in many cases to one per response. No server 
implementation code change is necessary to benefit from this change.
- To avoid even the last getObject() call, server implementations can attach a 
property definition to their PropertyData objects. The Property*Impl classes 
got new constructors that take the property definition instead of the property 
ID. Server implementations that use their own PropertyData implementations have 
also to implement the PropertyDataWithDefinition interface if they want to use 
this new optimization. 

> Improve how JSON response of CMIS query function is built
> ---------------------------------------------------------
>
>                 Key: CMIS-896
>                 URL: https://issues.apache.org/jira/browse/CMIS-896
>             Project: Chemistry
>          Issue Type: Improvement
>          Components: opencmis-server
>    Affects Versions: OpenCMIS 0.12.0
>            Reporter: Nicolas Brandt
>            Assignee: Florian Müller
>            Priority: Minor
>             Fix For: OpenCMIS 0.13.0
>
>         Attachments: query.patch
>
>
> JSON responses of CMIS queries seems to be built in an inefficient way.
> {code:java|title=org.apache.chemistry.opencmis.commons.impl.JSONConverter.java}
>     /**
>      * Converts a bag of properties.
>      */
>     public static JSONObject convert(final Properties properties, final 
> String objectId, final TypeCache typeCache,
>             final PropertyMode propertyMode, final boolean succinct, final 
> DateTimeFormat dateTimeFormat) {
>         if (properties == null) {
>             return null;
>         }
>         // get the type
>         TypeDefinition type = null;
>         if (typeCache != null) {
>             PropertyData<?> typeProp = 
> properties.getProperties().get(PropertyIds.OBJECT_TYPE_ID);
>             if (typeProp instanceof PropertyId) {
>                 String typeId = ((PropertyId) typeProp).getFirstValue();
>                 if (typeId != null) {
>                     type = typeCache.getTypeDefinition(typeId);
>                 }
>             }
>             if (type == null && objectId != null && propertyMode != 
> PropertyMode.CHANGE) {
>                 type = typeCache.getTypeDefinitionForObject(objectId);
>             }
>         }
>         JSONObject result = new JSONObject();
>         for (PropertyData<?> property : properties.getPropertyList()) {
>             assert property != null;
>             assert property.getId() != null;
>             PropertyDefinition<?> propDef = null;
>             if (typeCache != null) {
>                 propDef = typeCache.getPropertyDefinition(property.getId());
>             }
>             if (propDef == null && type != null) {
>                 propDef = type.getPropertyDefinitions().get(property.getId());
>             }
>             if (propDef == null && typeCache != null && objectId != null && 
> propertyMode != PropertyMode.CHANGE) {
>                 typeCache.getTypeDefinitionForObject(objectId);
>                 propDef = typeCache.getPropertyDefinition(property.getId());
>             }
>             String propId = (propertyMode == PropertyMode.QUERY ? 
> property.getQueryName() : property.getId());
>             if (propId == null) {
>                 throw new CmisRuntimeException("No query name or alias for 
> property '" + property.getId() + "'!");
>             }
>             result.put(propId, convert(property, propDef, succinct, 
> dateTimeFormat));
>         }
>         return result;
>     }
> {code}
> According to the quoted source code, building the JSON response of query 
> {{select cmis:objectId, cmis:name from cmis:document}} requires to call the 
> function ObjectService.getObjectById per each row returned.
> When the query returns 1000 rows and the CMIS server is backed with a 
> database it causes a significant performance slowdown.
> For example with the two following queries (each of them returns 1000 rows):
>  bq. select * from cmis:document
>  bq. select cmis:objectId, cmis:name from cmis:document
> The second one is more than 5x slower than the first one.
> A solution may be to add PropertyType and Cardinality informations into 
> PropertyData objects, so it's no longer necessary to retrieve properties 
> definitions.
> I have attached a svn diff file with the changes.



--
This message was sent by Atlassian JIRA
(v6.3.4#6332)

Reply via email to