package org.fastcatsearch.transport.vo; import org.apache.lucene.util.BytesRef; import org.fastcatsearch.common.io.Streamable; import org.fastcatsearch.ir.io.DataInput; import org.fastcatsearch.ir.io.DataOutput; import org.fastcatsearch.ir.query.RowExplanation; import org.fastcatsearch.ir.search.DocIdList; import org.fastcatsearch.ir.search.HitElement; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.IOException; import java.util.ArrayList; import java.util.List; public class StreamableHitElement implements Streamable { public static Logger logger = LoggerFactory.getLogger(StreamableHitElement.class); private HitElement[] hitElements; private int count; public StreamableHitElement() { } public StreamableHitElement(HitElement[] hitElements, int count) { this.hitElements = hitElements; this.count = count; } /* * collectionId와 shardId는 broker에서만 필요하므로 전송하지 않는다. * 브로커에서 직접만들어 사용한다. * */ @Override public void readFrom(DataInput input) throws IOException { count = input.readInt(); this.hitElements = new HitElement[count]; for (int hitElementInx = 0; hitElementInx < count; hitElementInx++) { int segmentSequence = input.readInt(); int docNo = input.readInt(); int score = input.readInt(); int hit = input.readInt(); int rankDataSize = input.readInt(); // logger.debug("read dataLength = {},{}", dataOffset, dataLength); BytesRef[] rankData = new BytesRef[rankDataSize]; for (int rankDataInx = 0; rankDataInx < rankDataSize; rankDataInx++) { rankData[rankDataInx] = new BytesRef(input.readVInt()); input.readBytes(rankData[rankDataInx]); } int explanationSize = input.readVInt(); List<RowExplanation> explanations = null; if (explanationSize > 0) { explanations = new ArrayList<RowExplanation>(); for (int i = 0; i < explanationSize; i++) { explanations.add(new RowExplanation(input.readString(), input.readVInt(), input.readString())); } } int bundleDocIdSize = input.readVInt(); DocIdList bundleDocIdList = null; int totalBundleSize = 0; if(bundleDocIdSize > 0) { bundleDocIdList = new DocIdList(bundleDocIdSize); for (int i = 0; i < bundleDocIdSize; i++) { bundleDocIdList.add(input.readVInt(), input.readVInt()); } totalBundleSize = input.readVInt(); } hitElements[hitElementInx] = new HitElement(segmentSequence, docNo, score, hit, rankData, explanations, bundleDocIdList, totalBundleSize); } } @Override public void writeTo(DataOutput output) throws IOException { output.writeInt(count); for (int hitElementInx = 0; hitElementInx < count; hitElementInx++) { HitElement hitElement = hitElements[hitElementInx]; BytesRef[] rankData = hitElement.rankData(); output.writeInt(hitElement.segmentSequence()); output.writeInt(hitElement.docNo()); output.writeInt(hitElement.score()); output.writeInt(hitElement.hit()); output.writeInt(hitElement.rankDataSize()); for (int i = 0; i < hitElement.rankDataSize(); i++) { output.writeVInt(rankData[i].length()); output.writeBytes(rankData[i]); } if(hitElement.rowExplanations() != null){ output.writeVInt(hitElement.rowExplanations().size()); for(RowExplanation exp : hitElement.rowExplanations()){ output.writeString(exp.getId()); output.writeVInt(exp.getScore()); output.writeString(exp.getDescription()); } }else{ output.writeVInt(0); } if(hitElement.getBundleDocIdList() != null){ DocIdList bundleDocIdList = hitElement.getBundleDocIdList(); output.writeVInt(bundleDocIdList.size()); for (int i = 0; i < bundleDocIdList.size(); i++) { output.writeVInt(bundleDocIdList.segmentSequence(i)); output.writeVInt(bundleDocIdList.docNo(i)); } output.writeVInt(hitElement.getTotalBundleSize()); }else{ output.writeVInt(0); } } } public HitElement[] getHitElementList() { return hitElements; } public int count() { return count; } }