func (mlog *MemoryLogStorage) GetMessages(index int64, count int64) (model.Messages, error) {
	// Index starts at leaderFirstIndex, our local index does not
	minFetch := index - mlog.firstIndex
	if minFetch < 0 || count < 1 {
		return model.EMPTY_MESSAGES, nil
	}
	if minFetch >= int64(len(mlog.offsets)) {
		return model.EMPTY_MESSAGES, nil
	}

	fetchPoint := mlog.offsets[minFetch]

	maxFetch := minFetch + int64(count)
	var targetBytes int
	if maxFetch >= int64(len(mlog.offsets)) {
		maxFetch = int64(len(mlog.offsets))
		targetBytes = len(mlog.data) - fetchPoint
	} else {
		targetBytes = mlog.offsets[maxFetch] - fetchPoint
	}

	reader := bytes.NewReader(mlog.data[fetchPoint:])

	msgs, _, err := model.MessagesFromReader(reader, targetBytes)

	return msgs, err
}
Exemple #2
0
/*
GetMessages returns as many messages as possible from the given start index up to the maximum message batch size

Cache has already been checked at this stage, so we use seeking in the file itself to find the messages.
*/
func (seg *Segment) GetMessages(index int64, targetMessageCount int) (msgs model.Messages, segmentRequiredOpening bool, err error) {
	seg.lock.Lock()
	defer seg.lock.Unlock()
	seg.statsGetMessageCalls++
	seg.lastAccessTime = time.Now()
	segmentRequiredOpening = false

	if !seg.segmentOpen {
		err := seg.openWhileHoldingLock(false)
		if err != nil {
			return model.EMPTY_MESSAGES, true, err
		}
		segmentRequiredOpening = true
	}

	localIndex := index - seg.firstIndex
	if localIndex >= int64(seg.msgCount) {
		//seg.node_log("Segment %v - requested for message index %v (local %v) which is beyond length %v\n", seg.filename, index, localIndex, len(seg.indexOffsetList))
		// Request for a message beyond our content - return empty handed.
		// This happens frequently when the leader is looking for messages that the peer hasn't seen and the peer is up to speed.
		return model.EMPTY_MESSAGES, segmentRequiredOpening, nil
	}
	_, err = seg.seekToIndexHoldingLock(index)
	if err != nil {
		return model.EMPTY_MESSAGES, false, err
	}

	// How much message data can we return?
	targetMessageBatchSize := seg.getBestReadSize(index, seg.filePosition, targetMessageCount)

	results, sizeRead, err := model.MessagesFromReader(seg.file, targetMessageBatchSize)
	seg.filePosition += int64(sizeRead)

	if err != nil {
		return model.EMPTY_MESSAGES, segmentRequiredOpening, err
	}

	if results.GetCount() == 0 {
		seg.node_log("Segment %v - requested for message index %v (local %v) which resulted in no content %v\n", seg.filename, index, localIndex, seg.msgCount)
	}

	return results, segmentRequiredOpening, nil
}