Changeset 4122


Ignore:
Timestamp:
2010-07-07 14:35:45 (3 years ago)
Author:
bruno
Message:

AvroConverter?: when deserializing records, do not rely on the TypeManager? to determine the primitive value type of fields, but rather transport this info as part of the Avro message. Otherwise:

  • for each field another remote call is done to retrieve its field type
  • this could be solved if in the future we would have a field type cache in the client, but right now it is not clear if we will ever have such cache
  • since the name of fields can change, the type of the transported field might not correspond to the field type loaded (from cache or direct). However, this issue is still present, since it know simply moves to the server side. Anyway, such name changes should be rare.
Location:
projects/lily/trunk/repository/impl/src
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • projects/lily/trunk/repository/impl/src/main/avro/lily.avpr

    r4121 r4122  
    1010        {"name": "namespace", "type": ["string", "null"]}, 
    1111        {"name": "name", "type": "string"} 
     12      ] 
     13    }, 
     14 
     15    { 
     16      "name": "AvroField", 
     17      "type": "record", 
     18      "fields": [ 
     19        {"name": "name", "type": "string"}, 
     20        {"name": "primitiveType", "type": "string"}, 
     21        {"name": "multiValue", "type": "boolean"}, 
     22        {"name": "hierarchical", "type": "boolean"}, 
     23        {"name": "value", "type": "bytes"} 
    1224      ] 
    1325    }, 
     
    2335        {"name": "scopeRecordTypeIds", "type": {"type": "map", "values": "string"}}, 
    2436        {"name": "scopeRecordTypeVersions", "type": {"type": "map", "values": "long"}}, 
    25         {"name": "fields", "type": {"type": "map", "values": "bytes"}}, 
     37        {"name": "fields", "type": {"type": "array", "items": "AvroField"}}, 
    2638        {"name": "fieldsToDelete", "type": {"type": "array", "items": "string"}} 
    2739      ] 
  • projects/lily/trunk/repository/impl/src/main/java/org/lilycms/repository/avro/AvroConverter.java

    r4121 r4122  
    5454            } 
    5555        } 
     56 
    5657        // Fields 
    57         Map<Utf8, ByteBuffer> fields = avroRecord.fields; 
    58         if (fields != null) { 
    59             for (Entry<Utf8, ByteBuffer> field : fields.entrySet()) { 
    60                 QName name = decodeQName(convert(field.getKey())); 
    61                 Object value = typeManager.getFieldTypeByName(name).getValueType().fromBytes(field.getValue().array()); 
     58        if (avroRecord.fields != null) { 
     59            for (AvroField field : avroRecord.fields) { 
     60                QName name = decodeQName(convert(field.name)); 
     61                ValueType valueType = typeManager.getValueType(convert(field.primitiveType), field.multiValue, field.hierarchical); 
     62                Object value = valueType.fromBytes(field.value.array()); 
    6263                record.setField(name, value); 
    6364            } 
    6465        } 
     66 
    6567        // FieldsToDelete 
    6668        GenericArray<Utf8> avroFieldsToDelete = avroRecord.fieldsToDelete; 
     
    104106            } 
    105107        } 
     108 
    106109        // Fields 
    107         avroRecord.fields = new HashMap<Utf8, ByteBuffer>(); 
     110        avroRecord.fields = new GenericData.Array<AvroField>(record.getFields().size(), Schema.createArray(AvroField.SCHEMA$)); 
    108111        for (Entry<QName, Object> field : record.getFields().entrySet()) { 
    109             QName name = field.getKey(); 
     112            AvroField avroField = new AvroField(); 
     113            avroField.name = convert(encodeQName(field.getKey())); 
     114 
    110115            FieldType fieldType; 
    111116            try { 
    112                 fieldType = typeManager.getFieldTypeByName(name); 
     117                fieldType = typeManager.getFieldTypeByName(field.getKey()); 
    113118            } catch (FieldTypeNotFoundException e) { 
    114119                throw convert(e); 
     
    116121                throw convert(e); 
    117122            } 
     123 
     124            avroField.primitiveType = convert(fieldType.getValueType().getPrimitive().getName()); 
     125            avroField.multiValue = fieldType.getValueType().isMultiValue(); 
     126            avroField.hierarchical = fieldType.getValueType().isHierarchical(); 
     127 
    118128            byte[] value = fieldType.getValueType().toBytes(field.getValue()); 
    119129            ByteBuffer byteBuffer = ByteBuffer.allocate(value.length); 
     
    121131            byteBuffer.put(value); 
    122132            byteBuffer.reset(); 
    123             avroRecord.fields.put(new Utf8(encodeQName(name)), byteBuffer); 
    124         } 
     133 
     134            avroField.value = byteBuffer; 
     135 
     136            avroRecord.fields.add(avroField); 
     137        } 
     138 
    125139        // FieldsToDelete 
    126140        List<QName> fieldsToDelete = record.getFieldsToDelete(); 
  • projects/lily/trunk/repository/impl/src/test/java/org/lilycms/repository/impl/test/AvroConverterTest.java

    r4100 r4122  
    346346        fieldType.getValueType(); 
    347347        expectLastCall().andReturn(valueType).anyTimes(); 
    348         control.replay(); 
     348        typeManager.getValueType("STRING", false, false); 
     349        expectLastCall().andReturn(valueType).anyTimes(); 
     350        control.replay(); 
     351 
    349352        converter = new AvroConverter(); 
    350353        converter.setRepository(repository); 
Note: See TracChangeset for help on using the changeset viewer.