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 }
/* 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 }