Skip to content

Commit

Permalink
fix touch with distributed folders
Browse files Browse the repository at this point in the history
  • Loading branch information
vintikzzz committed Dec 22, 2023
1 parent e59503d commit 6d823c3
Show file tree
Hide file tree
Showing 3 changed files with 71 additions and 62 deletions.
62 changes: 62 additions & 0 deletions server/services/common.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,67 @@
package services

import (
"crypto/sha1"
"fmt"
"github.com/pkg/errors"
"os"
"path"
"sort"
"strconv"
"strings"
)

const (
DataDirFlag = "data-dir"
)

func DistributeByHash(dirs []string, hash string) (string, error) {
sort.Strings(dirs)
hex := fmt.Sprintf("%x", sha1.Sum([]byte(hash)))[0:5]
num64, err := strconv.ParseInt(hex, 16, 64)
if err != nil {
return "", errors.Wrapf(err, "failed to parse hex from hex=%v infohash=%v", hex, hash)
}
num := int(num64 * 1000)
total := 1048575 * 1000
interval := total / len(dirs)
for i := 0; i < len(dirs); i++ {
if num < (i+1)*interval {
return dirs[i], nil
}
}
return "", errors.Wrapf(err, "failed to distribute infohash=%v", hash)
}

func GetDir(location string, hash string) (string, error) {
if strings.HasSuffix(location, "*") {
prefix := strings.TrimSuffix(location, "*")
dir, lp := path.Split(prefix)
if dir == "" {
dir = "."
}
files, err := os.ReadDir(dir)
if err != nil {
return "", err
}
dirs := []string{}
for _, f := range files {
if f.IsDir() && strings.HasPrefix(f.Name(), lp) {
dirs = append(dirs, f.Name())
}
}
if len(dirs) == 0 {
return prefix + "/" + hash, nil
} else if len(dirs) == 1 {
return dir + "/" + dirs[0] + "/" + hash, nil
} else {
d, err := DistributeByHash(dirs, hash)
if err != nil {
return "", err
}
return dir + "/" + d + "/" + hash, nil
}
} else {
return location + "/" + hash, nil
}
}
63 changes: 3 additions & 60 deletions server/services/mmap.go
Original file line number Diff line number Diff line change
@@ -1,20 +1,13 @@
package services

import (
"crypto/sha1"
"fmt"
"github.com/anacrolix/missinggo/v2"
"github.com/edsrzf/mmap-go"
"io"
"io/ioutil"
"log"
"os"
"path"
"path/filepath"
"sort"
"strconv"
"strings"

"github.com/anacrolix/missinggo/v2"
"github.com/edsrzf/mmap-go"

"github.com/anacrolix/torrent/metainfo"
"github.com/anacrolix/torrent/mmap_span"
Expand All @@ -31,59 +24,9 @@ func NewMMap(baseDir string) *mmapClientImpl {
baseDir: baseDir,
}
}
func (s *mmapClientImpl) distributeByHash(dirs []string, hash string) (string, error) {
sort.Strings(dirs)
hex := fmt.Sprintf("%x", sha1.Sum([]byte(hash)))[0:5]
num64, err := strconv.ParseInt(hex, 16, 64)
if err != nil {
return "", errors.Wrapf(err, "failed to parse hex from hex=%v infohash=%v", hex, hash)
}
num := int(num64 * 1000)
total := 1048575 * 1000
interval := total / len(dirs)
for i := 0; i < len(dirs); i++ {
if num < (i+1)*interval {
return dirs[i], nil
}
}
return "", errors.Wrapf(err, "failed to distribute infohash=%v", hash)
}

func (s *mmapClientImpl) getDir(location string, hash string) (string, error) {
if strings.HasSuffix(location, "*") {
prefix := strings.TrimSuffix(location, "*")
dir, lp := path.Split(prefix)
if dir == "" {
dir = "."
}
files, err := ioutil.ReadDir(dir)
if err != nil {
return "", err
}
dirs := []string{}
for _, f := range files {
if f.IsDir() && strings.HasPrefix(f.Name(), lp) {
dirs = append(dirs, f.Name())
}
}
if len(dirs) == 0 {
return prefix + "/" + hash, nil
} else if len(dirs) == 1 {
return dir + "/" + dirs[0] + "/" + hash, nil
} else {
d, err := s.distributeByHash(dirs, hash)
if err != nil {
return "", err
}
return dir + "/" + d + "/" + hash, nil
}
} else {
return location + "/" + hash, nil
}
}

func (s *mmapClientImpl) OpenTorrent(info *metainfo.Info, infoHash metainfo.Hash) (_ storage.TorrentImpl, err error) {
dir, err := s.getDir(s.baseDir, infoHash.HexString())
dir, err := GetDir(s.baseDir, infoHash.HexString())
if err != nil {
return
}
Expand Down
8 changes: 6 additions & 2 deletions server/services/touch_map.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,12 @@ func NewTouchMap(c *cli.Context) *TouchMap {
}

func (s *TouchMap) touch(h string) error {
f := s.p + "/" + h + ".touch"
_, err := os.Stat(f)
dir, err := GetDir(s.p, h)
if err != nil {
return err
}
f := dir + ".touch"
_, err = os.Stat(f)
if os.IsNotExist(err) {
file, err := os.Create(f)
if err != nil {
Expand Down

0 comments on commit 6d823c3

Please sign in to comment.