public ByteSegmentRef internalRead() {

      long absoluteValueOffset;

      int valueLength;

      if (readIndex == 0) {
        /*
         * Positioned to first.
         */

        /*
         * Extract information from reference word from slot table.
         */
        absoluteValueOffset =
            (valueRefWord & AbsoluteValueOffset.bitMask);

        // Position before the last written value.
        valueStore.writeBuffers.setReadPoint(absoluteValueOffset, readPos);

        if (isSingleRow) {
          /*
           * One element.
           */
          isNextEof = true;

          valueLength =
              (int) ((valueRefWord & SmallValueLength.bitMask) >> SmallValueLength.bitShift);
          boolean isValueLengthSmall = (valueLength != SmallValueLength.allBitsOn);
          if (!isValueLengthSmall) {

            // {Big Value Len} {Big Value Bytes}
            valueLength = valueStore.writeBuffers.readVInt(readPos);
          } else {

            // {Small Value Bytes}
            // (use small length from valueWordRef)
          }
        } else {
          /*
           * First of Multiple elements.
           */
          isNextEof = false;

          /*
           * Read the relative offset word at the beginning 2nd and beyond records.
           */
          long relativeOffsetWord = valueStore.writeBuffers.readVLong(readPos);

          long relativeOffset =
              (relativeOffsetWord & NextRelativeValueOffset.bitMask) >> NextRelativeValueOffset.bitShift;

          nextAbsoluteValueOffset = absoluteValueOffset - relativeOffset;

          valueLength =
              (int) ((valueRefWord & SmallValueLength.bitMask) >> SmallValueLength.bitShift);
          boolean isValueLengthSmall = (valueLength != SmallValueLength.allBitsOn);

          /*
           * Optionally, read current value's big length.  {Big Value Len} {Big Value Bytes}
           * Since this is the first record, the valueRefWord directs us.
           */
          if (!isValueLengthSmall) {
            valueLength = valueStore.writeBuffers.readVInt(readPos);
          }

          isNextLast = ((relativeOffsetWord & IsNextValueLastFlag.flagOnMask) != 0);
          isNextValueLengthSmall =
              ((relativeOffsetWord & IsNextValueLengthSmallFlag.flagOnMask) != 0);

          /*
           * Optionally, the next value's small length could be a 2nd integer...
           */
          if (isNextValueLengthSmall) {
            nextSmallValueLength = valueStore.writeBuffers.readVInt(readPos);
          } else {
            nextSmallValueLength = -1;
          }
       }

      } else {
        if (isNextEof) {
          return null;
        }

        absoluteValueOffset =  nextAbsoluteValueOffset;

        // Position before the last written value.
        valueStore.writeBuffers.setReadPoint(absoluteValueOffset, readPos);

        if (isNextLast) {
          /*
           * No relativeOffsetWord in last value.  (This was the first value written.)
           */
          isNextEof = true;

          if (isNextValueLengthSmall) {

            // {Small Value Bytes}
            valueLength = nextSmallValueLength;
          } else {

            // {Big Value Len} {Big Value Bytes}
            valueLength = valueStore.writeBuffers.readVInt(readPos);
          }
        } else {
          /*
           * {Rel Offset Word} [Big Value Len] [Next Value Small Len] {Value Bytes}
           *
           * 2nd and beyond records have a relative offset word at the beginning.
           */
          isNextEof = false;

          long relativeOffsetWord = valueStore.writeBuffers.readVLong(readPos);

          /*
           * Optionally, read current value's big length.  {Big Value Len} {Big Value Bytes}
           */
          if (isNextValueLengthSmall) {
            valueLength = nextSmallValueLength;
          } else {
            valueLength = valueStore.writeBuffers.readVInt(readPos);
          }

          long relativeOffset =
              (relativeOffsetWord & NextRelativeValueOffset.bitMask) >> NextRelativeValueOffset.bitShift;

          nextAbsoluteValueOffset = absoluteValueOffset - relativeOffset;

          isNextLast = ((relativeOffsetWord & IsNextValueLastFlag.flagOnMask) != 0);
          isNextValueLengthSmall =
              ((relativeOffsetWord & IsNextValueLengthSmallFlag.flagOnMask) != 0);

          /*
           * Optionally, the next value's small length could be a 2nd integer in the value's
           * information.
           */
          if (isNextValueLengthSmall) {
            nextSmallValueLength = valueStore.writeBuffers.readVInt(readPos);
          } else {
            nextSmallValueLength = -1;
          }
        }
      }

      // Our reading is positioned to the value.
      valueStore.writeBuffers.getByteSegmentRefToCurrent(byteSegmentRef, valueLength, readPos);

      readIndex++;
      return byteSegmentRef;
    }
Get detailed HashMap result position information to help diagnose exceptions.
ql/src/java/org/apache/hadoop/hive/ql/exec/vector/mapjoin/fast/VectorMapJoinFastValueStore.java