@Override
    void serialize(RandomAccessOutput byteStream, Object obj, ObjectInspector objInspector,
        boolean skipLengthPrefix, BooleanRef warnedOnceNullMapKey) {
      int lasti = 0;
      byte nullByte = 0;
      int size = serializers.length;

      int byteSizeStart = 0;
      int typeStart = 0;
      if (!skipLengthPrefix) {
        // 1/ reserve spaces for the byte size of the struct
        // which is a integer and takes four bytes
        byteSizeStart = byteStream.getLength();
        byteStream.reserve(4);
        typeStart = byteStream.getLength();
      }

      StructObjectInspector soi = (StructObjectInspector) objInspector;
      List<? extends StructField> fields = soi.getAllStructFieldRefs();
      for (int i = 0; i < size; ++i) {
        StructField structField = fields.get(i);
        fieldData[i] = soi.getStructFieldData(obj, structField);
      }

      for (int i = 0; i < size; ++i) {
        // set bit to 1 if a field is not null
        if (null != fieldData[i]) {
          nullByte |= 1 << (i % 8);
        }
        // write the null byte every eight elements or
        // if this is the last element and serialize the
        // corresponding 8 struct fields at the same time
        if (7 == i % 8 || i == size - 1) {
          byteStream.write(nullByte);
          for (int j = lasti; j <= i; j++) {
            serializers[j].serializeValue(
                byteStream, fieldData[j], fields.get(j).getFieldObjectInspector(),
                false, warnedOnceNullMapKey);
          }
          lasti = i + 1;
          nullByte = 0;
        }
      }

      if (!skipLengthPrefix) {
        // 3/ update the byte size of the struct
        int typeEnd = byteStream.getLength();
        int typeSize = typeEnd - typeStart;
        writeSizeAtOffset(byteStream, byteSizeStart, typeSize);
      }
    }
Abstract serializer class for serializing to LazyBinary format.
serde/src/java/org/apache/hadoop/hive/serde2/lazybinary/LazyBinarySerDe2.java