code: func (ms *FileMsgStore) removeFirstMsg(mindex *msgIndex, lockFile bool) error {
  	// Work with the first slice
  	slice := ms.files[ms.firstFSlSeq]
  	// Get the message index for the first valid message in this slice
  	if mindex == nil {
  		if lockFile || slice != ms.writeSlice {
  			ms.lockIndexFile(slice)
  		}
  		var err error
  		mindex, err = ms.getMsgIndex(slice, slice.firstSeq)
  		if lockFile || slice != ms.writeSlice {
  			ms.unlockIndexFile(slice)
  		}
  		if err != nil {
  			return err
  		}
  	}
  	// Size of the first message in this slice
  	firstMsgSize := mindex.msgSize
  	// For size, we count the size of serialized message + record header +
  	// the corresponding index record
  	size := uint64(firstMsgSize + msgRecordOverhead)
  	// Keep track of number of "removed" messages in this slice
  	slice.rmCount++
  	// Update total counts
  	ms.totalCount--
  	ms.totalBytes -= size
  	// Messages sequence is incremental with no gap on a given msgstore.
  	ms.first++
  	// Invalidate ms.firstMsg, it will be looked-up on demand.
  	ms.firstMsg = nil
  	// Invalidate ms.lastMsg if it was the last message being removed.
  	if ms.first > ms.last {
  		ms.lastMsg = nil
  	}
  	// Is file slice is "empty" and not the last one
  	if slice.msgsCount == slice.rmCount && len(ms.files) > 1 {
  		ms.removeFirstSlice()
  	} else {
  		// This is the new first message in this slice.
  		slice.firstSeq = ms.first
  	}
  	return nil
  }
docs: // removeFirstMsg "removes" the first message of the first slice.
  // If the slice is "empty" the file slice is removed.