package com.xiaomi.infra.galaxy.client.io; import java.io.IOException; import java.util.HashMap; import java.util.Map; import com.xiaomi.infra.galaxy.api.io.ByteArrayRecordWriter; import com.xiaomi.infra.galaxy.api.io.RecordWriter; import com.xiaomi.infra.galaxy.sds.thrift.Datum; import com.xiaomi.infra.galaxy.sds.thrift.DatumMapMeta; import com.xiaomi.infra.galaxy.sds.thrift.DatumMapRecord; import libthrift091.TException; import libthrift091.TSerializer; import libthrift091.protocol.TCompactProtocol; /** * This class is not thread safe */ class SDSDatumMapRecordWriter implements RecordWriter<Map<String, Datum>> { private ByteArrayRecordWriter writer; private Map<String, Short> keyIdLookupTable = new HashMap<String, Short>(); ; private TSerializer serializer = new TSerializer(new TCompactProtocol.Factory()); SDSDatumMapRecordWriter(ByteArrayRecordWriter writer, DatumMapMeta metadata) { this.writer = writer; if (metadata.getKeyIdMap() != null) { for (Map.Entry<Short, String> entry : metadata.getKeyIdMap().entrySet()) { keyIdLookupTable.put(entry.getValue(), entry.getKey()); } } } @Override public void append(Map<String, Datum> record) throws IOException { Map<Short, Datum> rec = new HashMap<Short, Datum>(); boolean containsAll = true; short maxKeyId = -1; for (Map.Entry<String, Datum> e : record.entrySet()) { Short keyId = keyIdLookupTable.get(e.getKey()); if (keyId == null) { containsAll = false; } else { if (maxKeyId < keyId) { maxKeyId = keyId; } rec.put(keyId, e.getValue()); } } DatumMapRecord dmr = new DatumMapRecord(); if (!containsAll) { Map<Short, String> newKeyIdMap = new HashMap<Short, String>(); for (Map.Entry<String, Datum> e : record.entrySet()) { Short keyId = keyIdLookupTable.get(e.getKey()); if (keyId == null) { keyId = ++maxKeyId; newKeyIdMap.put(keyId, e.getKey()); rec.put(keyId, e.getValue()); } } dmr.setKeyIdMap(newKeyIdMap); } byte[] bytes; try { bytes = serializer.serialize(dmr.setData(rec)); } catch (TException te) { throw new IOException("Failed to serialize record", te); } writer.append(bytes); } @Override public void seal() throws IOException { writer.seal(); } @Override public void close() throws IOException { writer.close(); } }