Add FindPackages()

The version inmemory is optimized, while the boltdb implementation is
not.

It returns a list of the same package but with all the versions present
in the db.
This commit is contained in:
Ettore Di Giacinto 2019-12-06 16:29:15 +01:00 committed by Ettore Di Giacinto
parent 556668fcc4
commit 57181d7cbf
3 changed files with 79 additions and 9 deletions

View File

@ -33,6 +33,7 @@ type PackageSet interface {
GetPackage(ID string) (Package, error)
Clean() error
FindPackage(Package) (Package, error)
FindPackages(p Package) ([]Package, error)
UpdatePackage(p Package) error
GetAllPackages(packages chan Package) error
RemovePackage(Package) error

View File

@ -22,6 +22,7 @@ import (
"sync"
"time"
version "github.com/hashicorp/go-version"
"github.com/pkg/errors"
storm "github.com/asdine/storm"
@ -293,3 +294,27 @@ func (db *BoltDatabase) FindPackageCandidate(p Package) (Package, error) {
return required, err
}
// FindPackages return the list of the packages beloging to cat/name (any versions)
// FIXME: Optimize, see inmemorydb
func (db *BoltDatabase) FindPackages(p Package) ([]Package, error) {
var versionsInWorld []Package
for _, w := range db.World() {
if w.GetName() != p.GetName() || w.GetCategory() != p.GetCategory() {
continue
}
v, err := version.NewVersion(w.GetVersion())
if err != nil {
return nil, err
}
constraints, err := version.NewConstraint(p.GetVersion())
if err != nil {
return nil, err
}
if constraints.Check(v) {
versionsInWorld = append(versionsInWorld, w)
}
}
return versionsInWorld, nil
}

View File

@ -18,28 +18,35 @@ package pkg
import (
"encoding/base64"
"encoding/json"
"errors"
"sync"
version "github.com/hashicorp/go-version"
"github.com/pkg/errors"
)
var DBInMemoryInstance = &InMemoryDatabase{
Mutex: &sync.Mutex{},
FileDatabase: map[string][]string{},
Database: map[string]string{}}
Mutex: &sync.Mutex{},
FileDatabase: map[string][]string{},
Database: map[string]string{},
CacheNoVersion: map[string]map[string]interface{}{},
}
type InMemoryDatabase struct {
*sync.Mutex
Database map[string]string
FileDatabase map[string][]string
Database map[string]string
FileDatabase map[string][]string
CacheNoVersion map[string]map[string]interface{}
}
func NewInMemoryDatabase(singleton bool) PackageDatabase {
// In memoryDB is a singleton
if !singleton {
return &InMemoryDatabase{
Mutex: &sync.Mutex{},
FileDatabase: map[string][]string{},
Database: map[string]string{}}
Mutex: &sync.Mutex{},
FileDatabase: map[string][]string{},
Database: map[string]string{},
CacheNoVersion: map[string]map[string]interface{}{},
}
}
return DBInMemoryInstance
}
@ -131,6 +138,16 @@ func (db *InMemoryDatabase) CreatePackage(p Package) (string, error) {
if err != nil {
return "", err
}
// Create extra cache between package -> []versions
db.Lock()
defer db.Unlock()
_, ok = db.CacheNoVersion[p.GetPackageName()]
if !ok {
db.CacheNoVersion[p.GetPackageName()] = make(map[string]interface{})
}
db.CacheNoVersion[p.GetPackageName()][p.GetVersion()] = nil
return ID, nil
}
@ -153,6 +170,33 @@ func (db *InMemoryDatabase) FindPackage(p Package) (Package, error) {
return db.GetPackage(p.GetFingerPrint())
}
// FindPackages return the list of the packages beloging to cat/name (any versions)
func (db *InMemoryDatabase) FindPackages(p Package) ([]Package, error) {
versions, ok := db.CacheNoVersion[p.GetPackageName()]
if !ok {
return nil, errors.New("No versions found for package")
}
var versionsInWorld []Package
for ve, _ := range versions {
v, err := version.NewVersion(ve)
if err != nil {
return nil, err
}
constraints, err := version.NewConstraint(p.GetVersion())
if err != nil {
return nil, err
}
if constraints.Check(v) {
w, err := db.FindPackage(&DefaultPackage{Name: p.GetName(), Category: p.GetCategory(), Version: ve})
if err != nil {
return nil, errors.Wrap(err, "Cache mismatch - this shouldn't happen")
}
versionsInWorld = append(versionsInWorld, w)
}
}
return versionsInWorld, nil
}
func (db *InMemoryDatabase) UpdatePackage(p Package) error {
_, enc, err := db.encodePackage(p)