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.ByteArrayRecordReader; import com.xiaomi.infra.galaxy.api.io.RecordReader; import com.xiaomi.infra.galaxy.io.thrift.RSFileHeader; 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.TDeserializer; import libthrift091.TException; import libthrift091.protocol.TCompactProtocol; /** * This class is not thread safe */ class SDSDatumMapRecordReader implements RecordReader<Map<String, Datum>> { private ByteArrayRecordReader reader; private Map<Short, String> keyIdMap = new HashMap<Short, String>(); SDSDatumMapRecordReader(ByteArrayRecordReader reader, DatumMapMeta meta) { this.reader = reader; if (meta != null && meta.getKeyIdMap() != null) { keyIdMap.putAll(meta.getKeyIdMap()); } } @Override public RSFileHeader readHeader() throws IOException { throw new UnsupportedOperationException("The header must be already read"); } @Override public boolean hasNext() throws IOException { return this.reader.hasNext(); } @Override public Map<String, Datum> next() throws IOException { byte[] bytes = this.reader.next(); TDeserializer deserializer = new TDeserializer(new TCompactProtocol.Factory()); DatumMapRecord dmr = new DatumMapRecord(); try { deserializer.deserialize(dmr, bytes); } catch (TException te) { throw new IOException("Failed to parse record", te); } if (dmr.isSetKeyIdMap()) { keyIdMap.putAll(dmr.getKeyIdMap()); } Map<String, Datum> record = new HashMap<String, Datum>(); for (Map.Entry<Short, Datum> entry : dmr.getData().entrySet()) { String key = keyIdMap.get(entry.getKey()); if (key == null) { throw new IllegalArgumentException("Illegal file, unknown key id: " + entry.getKey()); } record.put(key, entry.getValue()); } return record; } @Override public void close() throws IOException { this.reader.close(); } }