use of org.apache.ignite.internal.binary.BinaryMetadata in project ignite by apache.
the class PlatformContextImpl method writeMetadata0.
/**
* Write binary metadata.
*
* @param writer Writer.
* @param typeId Type id.
* @param meta Metadata.
*/
private void writeMetadata0(BinaryRawWriterEx writer, int typeId, BinaryType meta) {
if (meta == null)
writer.writeBoolean(false);
else {
writer.writeBoolean(true);
BinaryMetadata meta0 = ((BinaryTypeImpl) meta).metadata();
Map<String, BinaryFieldMetadata> fields = meta0.fieldsMap();
writer.writeInt(typeId);
writer.writeString(meta.typeName());
writer.writeString(meta.affinityKeyFieldName());
writer.writeInt(fields.size());
for (Map.Entry<String, BinaryFieldMetadata> e : fields.entrySet()) {
writer.writeString(e.getKey());
writer.writeInt(e.getValue().typeId());
writer.writeInt(e.getValue().fieldId());
}
if (meta.isEnum()) {
writer.writeBoolean(true);
Map<String, Integer> enumMap = meta0.enumMap();
writer.writeInt(enumMap.size());
for (Map.Entry<String, Integer> e : enumMap.entrySet()) {
writer.writeString(e.getKey());
writer.writeInt(e.getValue());
}
} else
writer.writeBoolean(false);
}
}
use of org.apache.ignite.internal.binary.BinaryMetadata in project ignite by apache.
the class CacheObjectBinaryProcessorImpl method addMeta.
/**
* {@inheritDoc}
*/
@Override
public void addMeta(final int typeId, final BinaryType newMeta) throws BinaryObjectException {
assert newMeta != null;
assert newMeta instanceof BinaryTypeImpl;
BinaryMetadata newMeta0 = ((BinaryTypeImpl) newMeta).metadata();
try {
BinaryMetadataHolder metaHolder = metadataLocCache.get(typeId);
BinaryMetadata oldMeta = metaHolder != null ? metaHolder.metadata() : null;
BinaryMetadata mergedMeta = BinaryUtils.mergeMetadata(oldMeta, newMeta0);
// metadata requested to be added is exactly the same as already presented in the cache
if (mergedMeta == oldMeta)
return;
MetadataUpdateResult res = transport.requestMetadataUpdate(mergedMeta).get();
assert res != null;
if (res.rejected())
throw res.error();
} catch (IgniteCheckedException e) {
throw new BinaryObjectException("Failed to update meta data for type: " + newMeta.typeName(), e);
}
}
use of org.apache.ignite.internal.binary.BinaryMetadata in project ignite by apache.
the class BinaryObjectBuilderImpl method serializeTo.
/**
* @param writer Writer.
* @param serializer Serializer.
*/
void serializeTo(BinaryWriterExImpl writer, BinaryBuilderSerializer serializer) {
try {
writer.preWrite(registeredType ? null : clsNameToWrite);
Set<Integer> remainsFlds = null;
BinaryType meta = ctx.metadata(typeId);
Map<String, BinaryFieldMetadata> fieldsMeta = null;
if (reader != null && BinaryUtils.hasSchema(flags)) {
BinarySchema schema = reader.schema();
Map<Integer, Object> assignedFldsById;
if (assignedVals != null) {
assignedFldsById = U.newHashMap(assignedVals.size());
for (Map.Entry<String, Object> entry : assignedVals.entrySet()) {
String name = entry.getKey();
Object val = entry.getValue();
int fieldId = ctx.fieldId(typeId, name);
assignedFldsById.put(fieldId, val);
if (val != REMOVED_FIELD_MARKER)
fieldsMeta = checkMetadata(meta, fieldsMeta, val, name, fieldId);
}
remainsFlds = assignedFldsById.keySet();
} else
assignedFldsById = Collections.emptyMap();
// Get footer details.
int fieldIdLen = BinaryUtils.fieldIdLength(flags);
int fieldOffsetLen = BinaryUtils.fieldOffsetLength(flags);
IgniteBiTuple<Integer, Integer> footer = BinaryUtils.footerAbsolute(reader, start);
int footerPos = footer.get1();
int footerEnd = footer.get2();
// Get raw position.
int rawPos = BinaryUtils.rawOffsetAbsolute(reader, start);
// Position reader on data.
reader.position(start + hdrLen);
int idx = 0;
while (reader.position() < rawPos) {
int fieldId = schema.fieldId(idx++);
int fieldLen = fieldPositionAndLength(footerPos, footerEnd, rawPos, fieldIdLen, fieldOffsetLen).get2();
// Position where reader will be placed afterwards.
int postPos = reader.position() + fieldLen;
footerPos += fieldIdLen + fieldOffsetLen;
if (assignedFldsById.containsKey(fieldId)) {
Object assignedVal = assignedFldsById.remove(fieldId);
if (assignedVal != REMOVED_FIELD_MARKER) {
writer.writeFieldId(fieldId);
serializer.writeValue(writer, assignedVal);
}
} else {
int type = fieldLen != 0 ? reader.readByte(0) : 0;
if (fieldLen != 0 && !BinaryUtils.isPlainArrayType(type) && BinaryUtils.isPlainType(type)) {
writer.writeFieldId(fieldId);
writer.write(reader.array(), reader.position(), fieldLen);
} else {
writer.writeFieldId(fieldId);
Object val;
if (fieldLen == 0)
val = null;
else if (readCache == null) {
val = reader.parseValue();
assert reader.position() == postPos;
} else
val = readCache.get(fieldId);
serializer.writeValue(writer, val);
}
}
reader.position(postPos);
}
}
if (assignedVals != null && (remainsFlds == null || !remainsFlds.isEmpty())) {
for (Map.Entry<String, Object> entry : assignedVals.entrySet()) {
Object val = entry.getValue();
if (val == REMOVED_FIELD_MARKER)
continue;
String name = entry.getKey();
int fieldId = ctx.fieldId(typeId, name);
if (remainsFlds != null && !remainsFlds.contains(fieldId))
continue;
writer.writeFieldId(fieldId);
serializer.writeValue(writer, val);
if (reader == null)
// Metadata has already been checked.
fieldsMeta = checkMetadata(meta, fieldsMeta, val, name, fieldId);
}
}
if (reader != null) {
// Write raw data if any.
int rawOff = BinaryUtils.rawOffsetAbsolute(reader, start);
int footerStart = BinaryUtils.footerStartAbsolute(reader, start);
if (rawOff < footerStart) {
writer.rawWriter();
writer.write(reader.array(), rawOff, footerStart - rawOff);
}
// Shift reader to the end of the object.
reader.position(start + BinaryUtils.length(reader, start));
}
writer.postWrite(true, registeredType);
// Update metadata if needed.
int schemaId = writer.schemaId();
BinarySchemaRegistry schemaReg = ctx.schemaRegistry(typeId);
if (schemaReg.schema(schemaId) == null) {
String typeName = this.typeName;
if (typeName == null) {
assert meta != null;
typeName = meta.typeName();
}
BinarySchema curSchema = writer.currentSchema();
String affFieldName0 = affFieldName;
if (affFieldName0 == null)
affFieldName0 = ctx.affinityKeyFieldName(typeId);
ctx.registerUserClassName(typeId, typeName, writer.failIfUnregistered(), false, JAVA_ID);
ctx.updateMetadata(typeId, new BinaryMetadata(typeId, typeName, fieldsMeta, affFieldName0, Collections.singleton(curSchema), false, null), writer.failIfUnregistered());
schemaReg.addSchema(curSchema.schemaId(), curSchema);
}
// Update hash code after schema is written.
writer.postWriteHashCode(registeredType ? null : clsNameToWrite);
} finally {
writer.popSchema();
}
}
use of org.apache.ignite.internal.binary.BinaryMetadata in project ignite by apache.
the class BinaryMetadataFileStore method mergeAndWriteMetadata.
/**
* Checks if binary metadata for the same typeId is already presented on disk. If so merges it with new metadata and
* stores the result. Otherwise just writes new metadata.
*
* @param binMeta new binary metadata to write to disk.
*/
void mergeAndWriteMetadata(BinaryMetadata binMeta) {
BinaryMetadata existingMeta = readMetadata(binMeta.typeId());
if (existingMeta != null) {
BinaryMetadata mergedMeta = BinaryUtils.mergeMetadata(existingMeta, binMeta);
writeMetadata(mergedMeta);
} else
writeMetadata(binMeta);
}
use of org.apache.ignite.internal.binary.BinaryMetadata in project ignite by apache.
the class CacheObjectBinaryProcessorImpl method onJoiningNodeDataReceived.
/**
* {@inheritDoc}
*/
@Override
public void onJoiningNodeDataReceived(DiscoveryDataBag.JoiningNodeDiscoveryData data) {
Map<Integer, BinaryMetadataHolder> newNodeMeta = (Map<Integer, BinaryMetadataHolder>) data.joiningNodeData();
if (newNodeMeta == null)
return;
UUID joiningNode = data.joiningNodeId();
for (Map.Entry<Integer, BinaryMetadataHolder> metaEntry : newNodeMeta.entrySet()) {
if (metadataLocCache.containsKey(metaEntry.getKey())) {
BinaryMetadataHolder localMetaHolder = metadataLocCache.get(metaEntry.getKey());
BinaryMetadata newMeta = metaEntry.getValue().metadata();
BinaryMetadata localMeta = localMetaHolder.metadata();
BinaryMetadata mergedMeta = mergeMetadata(localMeta, newMeta);
if (mergedMeta != localMeta) {
// put mergedMeta to local cache and store to disk
U.log(log, String.format("Newer version of existing BinaryMetadata[typeId=%d, typeName=%s] " + "is received from node %s; updating it locally", mergedMeta.typeId(), mergedMeta.typeName(), joiningNode));
metadataLocCache.put(metaEntry.getKey(), new BinaryMetadataHolder(mergedMeta, localMetaHolder.pendingVersion(), localMetaHolder.acceptedVersion()));
if (!ctx.clientNode())
metadataFileStore.writeMetadata(mergedMeta);
}
} else {
BinaryMetadataHolder newMetaHolder = metaEntry.getValue();
BinaryMetadata newMeta = newMetaHolder.metadata();
U.log(log, String.format("New BinaryMetadata[typeId=%d, typeName=%s] " + "is received from node %s; adding it locally", newMeta.typeId(), newMeta.typeName(), joiningNode));
metadataLocCache.put(metaEntry.getKey(), newMetaHolder);
if (!ctx.clientNode())
metadataFileStore.writeMetadata(newMeta);
}
}
}
Aggregations