chemistry-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Florian Müller (JIRA) <j...@apache.org>
Subject [jira] [Resolved] (CMIS-896) Improve how JSON response of CMIS query function is built
Date Fri, 06 Mar 2015 15:16:38 GMT

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

Mime
View raw message