package com.navercorp.pinpoint.common.server.bo.serializer.trace.v2.bitfield; import com.navercorp.pinpoint.common.server.bo.SpanBo; import com.navercorp.pinpoint.common.trace.LoggingInfo; import com.navercorp.pinpoint.common.util.BitFieldUtils; import org.apache.commons.collections.CollectionUtils; /** * @author Woonduk Kang(emeroad) */ public class SpanBitFiled { // 1bit public static final int SET_APPLICATION_SERVICE_TYPE_ENCODING_STRATEGY = 0; public static final int SET_ROOT = 1; public static final int SET_ERROR_CODE = 2; public static final int SET_HAS_EXCEPTION = 3; public static final int SET_FLAG = 4; public static final int SET_LOGGING_TRANSACTION_INFO = 5; public static final int SET_ANNOTATION = 6; private static final long ROOT_PARENT_SPAN_ID = -1; // used : 7bit // reserved : 1 bit private byte bitField = 0; public static SpanBitFiled build(SpanBo spanBo) { if (spanBo == null) { throw new NullPointerException("spanBo must not be null"); } final SpanBitFiled spanBitFiled = new SpanBitFiled(); if (spanBo.getServiceType() == spanBo.getApplicationServiceType()) { spanBitFiled.setApplicationServiceTypeEncodingStrategy(ServiceTypeEncodingStrategy.PREV_EQUALS); } else { spanBitFiled.setApplicationServiceTypeEncodingStrategy(ServiceTypeEncodingStrategy.RAW); } if (spanBo.getParentSpanId() == ROOT_PARENT_SPAN_ID) { spanBitFiled.setRoot(true); } if (spanBo.getErrCode() != 0) { spanBitFiled.setErrorCode(true); } if (spanBo.hasException()) { spanBitFiled.setHasException(true); } if (spanBo.getFlag() != 0) { spanBitFiled.setFlag(true); } if (spanBo.getLoggingTransactionInfo() != LoggingInfo.NOT_LOGGED.getCode()) { spanBitFiled.setLoggingTransactionInfo(true); } if (CollectionUtils.isNotEmpty(spanBo.getAnnotationBoList())) { spanBitFiled.setAnnotation(true); } return spanBitFiled; } public SpanBitFiled() { } public SpanBitFiled(byte bitField) { this.bitField = bitField; } public byte getBitField() { return bitField; } // for test void maskAll() { bitField = -1; } private void setBit(int position, boolean value) { this.bitField = BitFieldUtils.setBit(bitField, position, value); } private boolean testBit(int position) { return BitFieldUtils.testBit(bitField, position); } private int getBit(int position) { return BitFieldUtils.getBit(bitField, position); } public ServiceTypeEncodingStrategy getApplicationServiceTypeEncodingStrategy() { final int set = getBit(SET_APPLICATION_SERVICE_TYPE_ENCODING_STRATEGY); switch (set) { case 0: return ServiceTypeEncodingStrategy.PREV_EQUALS; case 1: return ServiceTypeEncodingStrategy.RAW; default: throw new IllegalArgumentException("SET_APPLICATION_SERVICE_TYPE_ENCODING_STRATEGY"); } } void setApplicationServiceTypeEncodingStrategy(ServiceTypeEncodingStrategy strategy) { switch (strategy) { case PREV_EQUALS: setBit(SET_APPLICATION_SERVICE_TYPE_ENCODING_STRATEGY, false); break; case RAW: setBit(SET_APPLICATION_SERVICE_TYPE_ENCODING_STRATEGY, true); break; default: throw new IllegalArgumentException("SET_APPLICATION_SERVICE_TYPE_ENCODING_STRATEGY"); } } public boolean isRoot() { return testBit(SET_ROOT); } // for test void setRoot(boolean root) { setBit(SET_ROOT, root); } public boolean isSetErrorCode() { return testBit(SET_ERROR_CODE); } // for test void setErrorCode(boolean errorCode) { setBit(SET_ERROR_CODE, errorCode); } public boolean isSetHasException() { return testBit(SET_HAS_EXCEPTION); } // for test void setHasException(boolean hasException) { setBit(SET_HAS_EXCEPTION, hasException); } public boolean isSetFlag() { return testBit(SET_FLAG); } // for test void setFlag(boolean flag) { setBit(SET_FLAG, flag); } public boolean isSetLoggingTransactionInfo() { return testBit(SET_LOGGING_TRANSACTION_INFO); } // for test void setLoggingTransactionInfo(boolean loggingTransactionInfo) { setBit(SET_LOGGING_TRANSACTION_INFO, loggingTransactionInfo); } public boolean isSetAnnotation() { return testBit(SET_ANNOTATION); } public void setAnnotation(boolean annotation) { setBit(SET_ANNOTATION, annotation); } }