@Override
    public byte[] encode(final LogEntry log) {
        Requires.requireNonNull(log, "Null log");

        final LogId logId = log.getId();
        final PBLogEntry.Builder builder = PBLogEntry.newBuilder() //
            .setType(log.getType()) //
            .setIndex(logId.getIndex()) //
            .setTerm(logId.getTerm());

        final List<PeerId> peers = log.getPeers();
        if (hasPeers(peers)) {
            encodePeers(builder, peers);
        }

        final List<PeerId> oldPeers = log.getOldPeers();
        if (hasPeers(oldPeers)) {
            encodeOldPeers(builder, oldPeers);
        }

        final List<PeerId> learners = log.getLearners();
        if (hasPeers(learners)) {
            encodeLearners(builder, learners);
        }
        final List<PeerId> oldLearners = log.getOldLearners();
        if (hasPeers(oldLearners)) {
            encodeOldLearners(builder, oldLearners);
        }

        if (log.hasChecksum()) {
            builder.setChecksum(log.getChecksum());
        }

        builder.setData(log.getData() != null ? ZeroByteStringHelper.wrap(log.getData()) : ByteString.EMPTY);

        final PBLogEntry pbLogEntry = builder.build();
        final int bodyLen = pbLogEntry.getSerializedSize();
        final byte[] ret = new byte[LogEntryV2CodecFactory.HEADER_SIZE + bodyLen];

        // write header
        int i = 0;
        for (; i < LogEntryV2CodecFactory.MAGIC_BYTES.length; i++) {
            ret[i] = LogEntryV2CodecFactory.MAGIC_BYTES[i];
        }
        ret[i++] = LogEntryV2CodecFactory.VERSION;
        // avoid memory copy for only 3 bytes
        for (; i < LogEntryV2CodecFactory.HEADER_SIZE; i++) {
            ret[i] = LogEntryV2CodecFactory.RESERVED[i - LogEntryV2CodecFactory.MAGIC_BYTES.length - 1];
        }

        // write body
        writeToByteArray(pbLogEntry, ret, i, bodyLen);

        return ret;
    }
V2 log entry encoder based on protobuf, see src/main/resources/log.proto

@author boyan(boyan@antfin.com)
jraft-core/src/main/java/com/alipay/sofa/jraft/entity/codec/v2/V2Encoder.java