package shortify import ( "sync" "github.com/hashicorp/golang-lru" bolt "go.etcd.io/bbolt" ) type Shortener struct { DataFolder string db *bolt.DB cache *lru.Cache accessCache *lru.Cache logChan chan VisitLog idPool *IDPool writeChan chan [2]string // queue of writes: [shortID, longURL] memStore sync.Map // thread-safe built-in } type Config struct { DataFolder string CacheSize int AccessLogSize int } func NewShortener(cfg Config) (*Shortener, error) { db, err := bolt.Open(cfg.DataFolder+"/database.db", 0600, nil) if err != nil { return nil, err } urlCache, _ := lru.New(cfg.CacheSize) accessCache, _ := lru.New(cfg.AccessLogSize) idPool, err := NewIDPool(db, 8, 10000, 2000) if err != nil { return nil, err } s := &Shortener{ DataFolder: cfg.DataFolder, db: db, cache: urlCache, accessCache: accessCache, logChan: make(chan VisitLog, 1000), writeChan: make(chan [2]string, 1000), idPool: idPool, } go s.startLogging() go s.asyncDBWriter() return s, nil }