<commit_before>package cache

import (
	"io"
	"os"
	"path/filepath"

	"github.com/pkg/errors"
	"github.com/restic/restic/internal/crypto"
	"github.com/restic/restic/internal/debug"
	"github.com/restic/restic/internal/fs"
	"github.com/restic/restic/internal/restic"
)

func (c *Cache) filename(h restic.Handle) string {
	if len(h.Name) < 2 {
		panic("Name is empty or too short")
	}
	subdir := h.Name[:2]
	return filepath.Join(c.Path, cacheLayoutPaths[h.Type], subdir, h.Name)
}

func (c *Cache) canBeCached(t restic.FileType) bool {
	if c == nil {
		return false
	}

	if _, ok := cacheLayoutPaths[t]; !ok {
		return false
	}

	return true
}

type readCloser struct {
	io.Reader
	io.Closer
}

// Load returns a reader that yields the contents of the file with the
// given handle. rd must be closed after use. If an error is returned, the
// ReadCloser is nil.
func (c *Cache) Load(h restic.Handle, length int, offset int64) (io.ReadCloser, error) {
	debug.Log("Load from cache: %v", h)
	if !c.canBeCached(h.Type) {
		return nil, errors.New("cannot be cached")
	}

	f, err := fs.Open(c.filename(h))
	if err != nil {
		return nil, errors.Wrap(err, "Open")
	}

	fi, err := f.Stat()
	if err != nil {
		_ = f.Close()
		return nil, errors.Wrap(err, "Stat")
	}

	if fi.Size() <= crypto.Extension {
		_ = f.Close()
		_ = c.Remove(h)
		return nil, errors.New("cached file is truncated, removing")
	}<commit_msg>cache: Add file name to error message<commit_after>package cache

import (
	"io"
	"os"
	"path/filepath"

	"github.com/pkg/errors"
	"github.com/restic/restic/internal/crypto"
	"github.com/restic/restic/internal/debug"
	"github.com/restic/restic/internal/fs"
	"github.com/restic/restic/internal/restic"
)

func (c *Cache) filename(h restic.Handle) string {
	if len(h.Name) < 2 {
		panic("Name is empty or too short")
	}
	subdir := h.Name[:2]
	return filepath.Join(c.Path, cacheLayoutPaths[h.Type], subdir, h.Name)
}

func (c *Cache) canBeCached(t restic.FileType) bool {
	if c == nil {
		return false
	}

	if _, ok := cacheLayoutPaths[t]; !ok {
		return false
	}

	return true
}

type readCloser struct {
	io.Reader
	io.Closer
}

// Load returns a reader that yields the contents of the file with the
// given handle. rd must be closed after use. If an error is returned, the
// ReadCloser is nil.
func (c *Cache) Load(h restic.Handle, length int, offset int64) (io.ReadCloser, error) {
	debug.Log("Load from cache: %v", h)
	if !c.canBeCached(h.Type) {
		return nil, errors.New("cannot be cached")
	}

	f, err := fs.Open(c.filename(h))
	if err != nil {
		return nil, errors.Wrap(err, "Open")
	}

	fi, err := f.Stat()
	if err != nil {
		_ = f.Close()
		return nil, errors.Wrap(err, "Stat")
	}

	if fi.Size() <= crypto.Extension {
		_ = f.Close()
		_ = c.Remove(h)
		return nil, errors.Errorf("cached file %v is truncated, removing", h)
	}
{'fraction_non_alphanumeric': 0.15121607331688403, 'fraction_numerical': 0.0028198801550934085, 'mean_word_length': 3.5848142164781907, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4973807', 'n_tokens_mistral': 1126, 'n_tokens_neox': 1080, 'n_words': 294}