feat: mem, local uploader

This commit is contained in:
loveuer
2024-04-10 22:10:09 +08:00
commit c5d0b8e45b
40 changed files with 8261 additions and 0 deletions

View File

@ -0,0 +1,113 @@
package blobs
import (
"context"
"errors"
"io"
"nf-repo/internal/interfaces"
"nf-repo/internal/model"
"nf-repo/internal/opt"
"os"
"path"
"sync"
)
type localHandler struct {
base string
sync.Mutex
}
func (l *localHandler) path(hash model.Hash) string {
//return path.Join(l.base, hash.Hex)
dir := path.Join(l.base, hash.Hex[:2], hash.Hex[2:4])
_ = os.MkdirAll(dir, 0755)
return path.Join(dir, hash.Hex)
}
func (l *localHandler) Get(ctx context.Context, repo string, hash model.Hash) (io.ReadCloser, error) {
var (
err error
f *os.File
)
l.Lock()
defer l.Unlock()
if f, err = os.Open(l.path(hash)); err != nil {
if errors.Is(err, os.ErrNotExist) {
return nil, opt.ErrNotFound
}
return nil, err
}
return f, nil
}
func (l *localHandler) Stat(ctx context.Context, repo string, hash model.Hash) (int64, error) {
var (
err error
info os.FileInfo
)
l.Lock()
defer l.Unlock()
if info, err = os.Stat(l.path(hash)); err != nil {
if errors.Is(err, os.ErrNotExist) {
return 0, opt.ErrNotFound
}
return 0, err
}
return info.Size(), nil
}
func (l *localHandler) Put(ctx context.Context, repo string, hash model.Hash, rc io.ReadCloser) error {
var (
err error
f *os.File
)
l.Lock()
defer l.Unlock()
if f, err = os.OpenFile(l.path(hash), os.O_CREATE|os.O_RDWR|os.O_TRUNC, 0644); err != nil {
return err
}
if _, err = io.Copy(f, rc); err != nil {
return err
}
return nil
}
func (l *localHandler) Delete(ctx context.Context, repo string, hash model.Hash) error {
var (
err error
info os.FileInfo
filename = l.path(hash)
)
l.Lock()
defer l.Unlock()
if info, err = os.Stat(filename); err != nil {
if errors.Is(err, os.ErrNotExist) {
return opt.ErrNotFound
}
return err
}
_ = info
return os.Remove(filename)
}
func NewLocalBlobHandler(baseDir string) interfaces.BlobHandler {
_ = os.MkdirAll(baseDir, 0755)
return &localHandler{base: baseDir}
}

View File

@ -0,0 +1,77 @@
package blobs
import (
"bytes"
"context"
"io"
"nf-repo/internal/interfaces"
"nf-repo/internal/model"
"nf-repo/internal/opt"
"sync"
)
type bytesCloser struct {
*bytes.Reader
}
func (r *bytesCloser) Close() error {
return nil
}
type memHandler struct {
m map[string][]byte
lock sync.Mutex
}
func NewMemBlobHandler() interfaces.BlobHandler {
return &memHandler{
m: map[string][]byte{},
}
}
func (m *memHandler) Stat(_ context.Context, _ string, h model.Hash) (int64, error) {
m.lock.Lock()
defer m.lock.Unlock()
bs, found := m.m[h.String()]
if !found {
return 0, opt.ErrNotFound
}
return int64(len(bs)), nil
}
func (m *memHandler) Get(_ context.Context, _ string, h model.Hash) (io.ReadCloser, error) {
m.lock.Lock()
defer m.lock.Unlock()
bs, found := m.m[h.String()]
if !found {
return nil, opt.ErrNotFound
}
return &bytesCloser{bytes.NewReader(bs)}, nil
}
func (m *memHandler) Put(_ context.Context, _ string, h model.Hash, rc io.ReadCloser) error {
m.lock.Lock()
defer m.lock.Unlock()
defer rc.Close()
all, err := io.ReadAll(rc)
if err != nil {
return err
}
m.m[h.String()] = all
return nil
}
func (m *memHandler) Delete(_ context.Context, _ string, h model.Hash) error {
m.lock.Lock()
defer m.lock.Unlock()
if _, found := m.m[h.String()]; !found {
return opt.ErrNotFound
}
delete(m.m, h.String())
return nil
}