perf: 拆分规划策略

This commit is contained in:
voocel
2026-03-13 00:19:21 +08:00
parent 16e790a372
commit 7488198461
24 changed files with 1543 additions and 487 deletions

View File

@@ -5,11 +5,13 @@ import (
"fmt"
"os"
"path/filepath"
"sync"
)
// Store 封装小说输出目录,提供所有状态读写操作。
type Store struct {
dir string
mu sync.RWMutex
}
// NewStore 创建状态管理器dir 为小说输出根目录。
@@ -36,19 +38,61 @@ func (s *Store) path(rel string) string {
}
func (s *Store) readFile(rel string) ([]byte, error) {
return os.ReadFile(s.path(rel))
s.mu.RLock()
defer s.mu.RUnlock()
return s.readFileUnlocked(rel)
}
func (s *Store) writeFile(rel string, data []byte) error {
s.mu.Lock()
defer s.mu.Unlock()
return s.writeFileUnlocked(rel, data)
}
func (s *Store) readFileUnlocked(rel string) ([]byte, error) {
return os.ReadFile(s.path(rel))
}
func (s *Store) writeFileUnlocked(rel string, data []byte) error {
p := s.path(rel)
if err := os.MkdirAll(filepath.Dir(p), 0o755); err != nil {
return err
}
return os.WriteFile(p, data, 0o644)
tmp, err := os.CreateTemp(filepath.Dir(p), filepath.Base(p)+".tmp-*")
if err != nil {
return err
}
tmpPath := tmp.Name()
defer func() {
_ = os.Remove(tmpPath)
}()
if _, err := tmp.Write(data); err != nil {
_ = tmp.Close()
return err
}
if err := tmp.Chmod(0o644); err != nil {
_ = tmp.Close()
return err
}
if err := tmp.Sync(); err != nil {
_ = tmp.Close()
return err
}
if err := tmp.Close(); err != nil {
return err
}
return os.Rename(tmpPath, p)
}
func (s *Store) readJSON(rel string, v any) error {
data, err := s.readFile(rel)
s.mu.RLock()
defer s.mu.RUnlock()
return s.readJSONUnlocked(rel, v)
}
func (s *Store) readJSONUnlocked(rel string, v any) error {
data, err := s.readFileUnlocked(rel)
if err != nil {
return err
}
@@ -56,21 +100,41 @@ func (s *Store) readJSON(rel string, v any) error {
}
func (s *Store) writeJSON(rel string, v any) error {
s.mu.Lock()
defer s.mu.Unlock()
return s.writeJSONUnlocked(rel, v)
}
func (s *Store) writeJSONUnlocked(rel string, v any) error {
data, err := json.MarshalIndent(v, "", " ")
if err != nil {
return err
}
return s.writeFile(rel, data)
return s.writeFileUnlocked(rel, data)
}
func (s *Store) writeMarkdown(rel string, content string) error {
return s.writeFile(rel, []byte(content))
s.mu.Lock()
defer s.mu.Unlock()
return s.writeFileUnlocked(rel, []byte(content))
}
func (s *Store) removeFile(rel string) error {
s.mu.Lock()
defer s.mu.Unlock()
return s.removeFileUnlocked(rel)
}
func (s *Store) removeFileUnlocked(rel string) error {
err := os.Remove(s.path(rel))
if os.IsNotExist(err) {
return nil
}
return err
}
func (s *Store) withWriteLock(fn func() error) error {
s.mu.Lock()
defer s.mu.Unlock()
return fn()
}