NAM-APJATEL-BACKEND/utils/service/geoCache_service.go

80 lines
1.7 KiB
Go

package service
import (
"fmt"
"log"
"sync"
"sync/atomic"
)
type CacheStats struct {
Hits int64
Misses int64
Size int
}
type CachedGeocoder struct {
underlying GeocodingService
cache map[string]string
mutex sync.RWMutex
hits int64
misses int64
}
func NewCachedGeocodingService(underlying GeocodingService) *CachedGeocoder {
return &CachedGeocoder{
underlying: underlying,
cache: make(map[string]string),
}
}
func (g *CachedGeocoder) GetAddressFromCoordinates(latitude, longitude float64) (string, error) {
cacheKey := fmt.Sprintf("%.6f,%.6f", latitude, longitude)
// Check cache first
g.mutex.RLock()
if address, ok := g.cache[cacheKey]; ok {
g.mutex.RUnlock()
atomic.AddInt64(&g.hits, 1)
log.Printf("CACHE HIT: Coordinates (%.6f,%.6f) found in cache", latitude, longitude)
return address, nil
}
g.mutex.RUnlock()
log.Printf("CACHE MISS: Coordinates (%.6f,%.6f) not in cache, fetching from service", latitude, longitude)
atomic.AddInt64(&g.misses, 1)
// Not in cache, call the underlying service
address, err := g.underlying.GetAddressFromCoordinates(latitude, longitude)
if err != nil {
return "", err
}
// Cache the result
g.mutex.Lock()
g.cache[cacheKey] = address
g.mutex.Unlock()
log.Printf("CACHE UPDATE: Coordinates (%.6f,%.6f) added to cache", latitude, longitude)
return address, nil
}
// GetStats returns the current cache statistics
func (g *CachedGeocoder) GetStats() CacheStats {
g.mutex.RLock()
stats := CacheStats{
Hits: g.hits,
Misses: g.misses,
Size: len(g.cache),
}
g.mutex.RUnlock()
return stats
}
// ClearCache empties the cache
func (g *CachedGeocoder) ClearCache() {
g.mutex.Lock()
g.cache = make(map[string]string)
g.mutex.Unlock()
}