diff --git a/experimental/clashapi/cachefile/cache.go b/experimental/clashapi/cachefile/cache.go index d2850067..adb4bc35 100644 --- a/experimental/clashapi/cachefile/cache.go +++ b/experimental/clashapi/cachefile/cache.go @@ -17,10 +17,12 @@ var bucketSelected = []byte("selected") var _ adapter.ClashCacheFile = (*CacheFile)(nil) type CacheFile struct { - DB *bbolt.DB - cacheID []byte - saveAccess sync.RWMutex - saveCache map[netip.Addr]string + DB *bbolt.DB + cacheID []byte + saveAccess sync.RWMutex + saveDomain map[netip.Addr]string + saveAddress4 map[string]netip.Addr + saveAddress6 map[string]netip.Addr } func Open(path string, cacheID string) (*CacheFile, error) { @@ -53,10 +55,15 @@ func Open(path string, cacheID string) (*CacheFile, error) { return nil }) }) + if err != nil { + return nil, err + } return &CacheFile{ - DB: db, - cacheID: cacheIDBytes, - saveCache: make(map[netip.Addr]string), + DB: db, + cacheID: cacheIDBytes, + saveDomain: make(map[netip.Addr]string), + saveAddress4: make(map[string]netip.Addr), + saveAddress6: make(map[string]netip.Addr), }, nil } diff --git a/experimental/clashapi/cachefile/fakeip.go b/experimental/clashapi/cachefile/fakeip.go index a180ccd3..cdc279f5 100644 --- a/experimental/clashapi/cachefile/fakeip.go +++ b/experimental/clashapi/cachefile/fakeip.go @@ -22,7 +22,7 @@ var ( func (c *CacheFile) FakeIPMetadata() *adapter.FakeIPMetadata { var metadata adapter.FakeIPMetadata - err := c.DB.View(func(tx *bbolt.Tx) error { + err := c.DB.Batch(func(tx *bbolt.Tx) error { bucket := tx.Bucket(bucketFakeIP) if bucket == nil { return nil @@ -31,6 +31,10 @@ func (c *CacheFile) FakeIPMetadata() *adapter.FakeIPMetadata { if len(metadataBinary) == 0 { return os.ErrInvalid } + err := bucket.Delete(keyMetadata) + if err != nil { + return err + } return metadata.UnmarshalBinary(metadataBinary) }) if err != nil { @@ -77,7 +81,12 @@ func (c *CacheFile) FakeIPStore(address netip.Addr, domain string) error { func (c *CacheFile) FakeIPStoreAsync(address netip.Addr, domain string, logger logger.Logger) { c.saveAccess.Lock() - c.saveCache[address] = domain + c.saveDomain[address] = domain + if address.Is4() { + c.saveAddress4[domain] = address + } else { + c.saveAddress6[domain] = address + } c.saveAccess.Unlock() go func() { err := c.FakeIPStore(address, domain) @@ -85,14 +94,19 @@ func (c *CacheFile) FakeIPStoreAsync(address netip.Addr, domain string, logger l logger.Warn("save FakeIP address pair: ", err) } c.saveAccess.Lock() - delete(c.saveCache, address) + delete(c.saveDomain, address) + if address.Is4() { + delete(c.saveAddress4, domain) + } else { + delete(c.saveAddress6, domain) + } c.saveAccess.Unlock() }() } func (c *CacheFile) FakeIPLoad(address netip.Addr) (string, bool) { c.saveAccess.RLock() - cachedDomain, cached := c.saveCache[address] + cachedDomain, cached := c.saveDomain[address] c.saveAccess.RUnlock() if cached { return cachedDomain, true @@ -110,6 +124,20 @@ func (c *CacheFile) FakeIPLoad(address netip.Addr) (string, bool) { } func (c *CacheFile) FakeIPLoadDomain(domain string, isIPv6 bool) (netip.Addr, bool) { + var ( + cachedAddress netip.Addr + cached bool + ) + c.saveAccess.RLock() + if !isIPv6 { + cachedAddress, cached = c.saveAddress4[domain] + } else { + cachedAddress, cached = c.saveAddress6[domain] + } + c.saveAccess.RUnlock() + if cached { + return cachedAddress, true + } var address netip.Addr _ = c.DB.View(func(tx *bbolt.Tx) error { var bucket *bbolt.Bucket