func (h *reqHandler) lazilyRespond(start, end uint64) { partSize := h.Cache.Storage.PartSize() indexes := utils.BreakInIndexes(h.objID, start, end, partSize) startOffset := start % partSize var shouldReturn = false for i := 0; i < len(indexes); { contents, partsCount, err := h.getContents(indexes, i) if err != nil { h.Logger.Errorf("[%p] Unexpected error while trying to load %s from storage: %s", h.req, indexes[i], err) return } if i == 0 && startOffset > 0 { contents, err = utils.SkipReadCloser(contents, int64(startOffset)) if err != nil { h.Logger.Errorf("[%p] Unexpected error while trying to skip %d from %s : %s", h.req, startOffset, indexes[i], err) return } } if i+partsCount == len(indexes) { endLimit := uint64(partsCount-1)*partSize + end%partSize + 1 if i == 0 { endLimit -= startOffset } contents = utils.LimitReadCloser(contents, int64(endLimit)) //!TODO: fix int conversion } if copied, err := io.Copy(h.resp, contents); err != nil { h.Logger.Logf("[%p] Error sending contents after %d bytes of %s, parts[%d-%d]: %s", h.req, copied, h.objID, i, i+partsCount-1, err) shouldReturn = true } //!TODO: compare the copied length with the expected if err := contents.Close(); err != nil { h.Logger.Errorf("[%p] Unexpected error while closing content reader for %s, parts[%d-%d]: %s", h.req, h.objID, i, i+partsCount-1, err) } if shouldReturn { return } i += partsCount } }
func checkParts(t *testing.T, start, length uint64, cz *types.CacheZone, oid *types.ObjectID) { partSize := cz.Storage.PartSize() indexes := utils.BreakInIndexes(oid, start, start+length-1, partSize) prefix := fmt.Sprintf("[PartWriter(%d,%d),Storage(%d)]", start, length, partSize) if len(indexes) > 0 && start%partSize != 0 { checkPartIsMissing(t, prefix+"first part", cz.Storage, indexes[0]) indexes = indexes[1:] } if len(indexes) > 0 && (start+length)%partSize != 0 && (start+length) != inputSize { checkPartIsMissing(t, prefix+"last part", cz.Storage, indexes[len(indexes)-1]) indexes = indexes[:len(indexes)-1] } for _, idx := range indexes { partNum := uint64(idx.Part) expected := input[partSize*partNum : umin(inputSize, (partNum+1)*partSize)] checkPart(t, fmt.Sprintf("%s part %d", prefix, partNum), expected, cz.Storage, idx) } }