Add db copy and clone

This commit is contained in:
Ettore Di Giacinto
2020-12-19 17:45:50 +01:00
parent e52bc4f2b2
commit 736c9470cf
7 changed files with 79 additions and 28 deletions

View File

@@ -236,14 +236,11 @@ func (l *LuetInstaller) computeSwap(syncedRepos Repositories, toRemove pkg.Packa
toInstall = syncedRepos.ResolveSelectors(toInstall) toInstall = syncedRepos.ResolveSelectors(toInstall)
// First check what would have been done // First check what would have been done
installedtmp := pkg.NewInMemoryDatabase(false) installedtmp, err := s.Database.Copy()
if err != nil {
for _, i := range s.Database.World() { return nil, nil, nil, nil, errors.Wrap(err, "Failed create temporary in-memory db")
_, err := installedtmp.CreatePackage(i)
if err != nil {
return nil, nil, nil, nil, errors.Wrap(err, "Failed create temporary in-memory db")
}
} }
systemAfterChanges := &System{Database: installedtmp} systemAfterChanges := &System{Database: installedtmp}
packs, err := l.computeUninstall(systemAfterChanges, toRemove...) packs, err := l.computeUninstall(systemAfterChanges, toRemove...)
@@ -772,13 +769,10 @@ func (l *LuetInstaller) computeUninstall(s *System, packs ...pkg.Package) (pkg.P
// Create a temporary DB with the installed packages // Create a temporary DB with the installed packages
// so the solver is much faster finding the deptree // so the solver is much faster finding the deptree
installedtmp := pkg.NewInMemoryDatabase(false) // First check what would have been done
installedtmp, err := s.Database.Copy()
for _, i := range s.Database.World() { if err != nil {
_, err := installedtmp.CreatePackage(i) return toUninstall, errors.Wrap(err, "Failed create temporary in-memory db")
if err != nil {
return toUninstall, errors.Wrap(err, "Failed create temporary in-memory db")
}
} }
if !l.Options.NoDeps { if !l.Options.NoDeps {

View File

@@ -28,6 +28,9 @@ type PackageDatabase interface {
} }
type PackageSet interface { type PackageSet interface {
Clone(PackageDatabase) error
Copy() (PackageDatabase, error)
GetRevdeps(p Package) (Packages, error) GetRevdeps(p Package) (Packages, error)
GetPackages() []string //Ids GetPackages() []string //Ids
CreatePackage(pkg Package) (string, error) CreatePackage(pkg Package) (string, error)

View File

@@ -47,6 +47,14 @@ func NewBoltDatabase(path string) PackageDatabase {
return &BoltDatabase{Path: path, ProvidesDatabase: map[string]map[string]Package{}} return &BoltDatabase{Path: path, ProvidesDatabase: map[string]map[string]Package{}}
} }
func (db *BoltDatabase) Clone(to PackageDatabase) error {
return clone(db, to)
}
func (db *BoltDatabase) Copy() (PackageDatabase, error) {
return copy(db)
}
func (db *BoltDatabase) Get(s string) (string, error) { func (db *BoltDatabase) Get(s string) (string, error) {
bolt, err := storm.Open(db.Path, storm.BoltOptions(0600, &bbolt.Options{Timeout: 30 * time.Second})) bolt, err := storm.Open(db.Path, storm.BoltOptions(0600, &bbolt.Options{Timeout: 30 * time.Second}))
if err != nil { if err != nil {

View File

@@ -0,0 +1,38 @@
// Copyright © 2020 Ettore Di Giacinto <mudler@gentoo.org>
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License along
// with this program; if not, see <http://www.gnu.org/licenses/>.
package pkg
import "github.com/pkg/errors"
func clone(src, dst PackageDatabase) error {
for _, i := range src.World() {
_, err := dst.CreatePackage(i)
if err != nil {
return errors.Wrap(err, "Failed create package "+i.HumanReadableString())
}
}
return nil
}
func copy(src PackageDatabase) (PackageDatabase, error) {
dst := NewInMemoryDatabase(false)
if err := clone(src, dst); err != nil {
return dst, errors.Wrap(err, "Failed create temporary in-memory db")
}
return dst, nil
}

View File

@@ -270,6 +270,14 @@ func (db *InMemoryDatabase) getProvide(p Package) (Package, error) {
return db.FindPackage(pa) return db.FindPackage(pa)
} }
func (db *InMemoryDatabase) Clone(to PackageDatabase) error {
return clone(db, to)
}
func (db *InMemoryDatabase) Copy() (PackageDatabase, error) {
return copy(db)
}
func (db *InMemoryDatabase) encodePackage(p Package) (string, string, error) { func (db *InMemoryDatabase) encodePackage(p Package) (string, string, error) {
pd, ok := p.(*DefaultPackage) pd, ok := p.(*DefaultPackage)
if !ok { if !ok {

View File

@@ -446,10 +446,9 @@ func (s *Parallel) UpgradeUniverse(dropremoved bool) (pkg.Packages, PackagesAsse
removed := pkg.Packages{} removed := pkg.Packages{}
// TODO: this is memory expensive, we need to optimize this // TODO: this is memory expensive, we need to optimize this
universe := pkg.NewInMemoryDatabase(false) universe, err := s.DefinitionDatabase.Copy()
if err != nil {
for _, p := range s.DefinitionDatabase.World() { return nil, nil, errors.Wrap(err, "couldn't build world copy")
universe.CreatePackage(p)
} }
for _, p := range s.Installed() { for _, p := range s.Installed() {
universe.CreatePackage(p) universe.CreatePackage(p)
@@ -558,9 +557,9 @@ func (s *Parallel) Upgrade(checkconflicts, full bool) (pkg.Packages, PackagesAss
toInstall := pkg.Packages{} toInstall := pkg.Packages{}
// we do this in memory so we take into account of provides // we do this in memory so we take into account of provides
universe := pkg.NewInMemoryDatabase(false) universe, err := s.DefinitionDatabase.Copy()
for _, p := range s.DefinitionDatabase.World() { if err != nil {
universe.CreatePackage(p) return nil, nil, errors.Wrap(err, "Could not copy def db")
} }
installedcopy := pkg.NewInMemoryDatabase(false) installedcopy := pkg.NewInMemoryDatabase(false)

View File

@@ -402,10 +402,11 @@ func (s *Solver) UpgradeUniverse(dropremoved bool) (pkg.Packages, PackagesAssert
replacements := map[pkg.Package]pkg.Package{} replacements := map[pkg.Package]pkg.Package{}
// TODO: this is memory expensive, we need to optimize this // TODO: this is memory expensive, we need to optimize this
universe := pkg.NewInMemoryDatabase(false) universe, err := s.DefinitionDatabase.Copy()
for _, p := range s.DefinitionDatabase.World() { if err != nil {
universe.CreatePackage(p) return nil, nil, errors.Wrap(err, "Failed copying db")
} }
for _, p := range s.Installed() { for _, p := range s.Installed() {
universe.CreatePackage(p) universe.CreatePackage(p)
} }
@@ -501,10 +502,10 @@ func (s *Solver) Upgrade(checkconflicts, full bool) (pkg.Packages, PackagesAsser
toUninstall := pkg.Packages{} toUninstall := pkg.Packages{}
toInstall := pkg.Packages{} toInstall := pkg.Packages{}
// we do this in memory so we take into account of provides // we do this in memory so we take into account of provides, and its faster
universe := pkg.NewInMemoryDatabase(false) universe, err := s.DefinitionDatabase.Copy()
for _, p := range s.DefinitionDatabase.World() { if err != nil {
universe.CreatePackage(p) return nil, nil, errors.Wrap(err, "failed creating db copy")
} }
installedcopy := pkg.NewInMemoryDatabase(false) installedcopy := pkg.NewInMemoryDatabase(false)