Ver Fonte

Merge pull request #44160 from thaJeztah/viewdb_no_interface

container: remove ViewDB and View interfaces, use concrete types
Sebastiaan van Stijn há 2 anos atrás
pai
commit
8e2fd56394
5 ficheiros alterados com 30 adições e 47 exclusões
  1. 1 1
      container/container.go
  2. 24 41
      container/view.go
  3. 1 1
      container/view_test.go
  4. 1 1
      daemon/daemon.go
  5. 3 3
      daemon/list.go

+ 1 - 1
container/container.go

@@ -193,7 +193,7 @@ func (container *Container) toDisk() (*Container, error) {
 
 // CheckpointTo makes the Container's current state visible to queries, and persists state.
 // Callers must hold a Container lock.
-func (container *Container) CheckpointTo(store ViewDB) error {
+func (container *Container) CheckpointTo(store *ViewDB) error {
 	deepCopy, err := container.toDisk()
 	if err != nil {
 		return err

+ 24 - 41
container/view.go

@@ -77,27 +77,6 @@ type nameAssociation struct {
 	containerID string
 }
 
-// ViewDB provides an in-memory transactional (ACID) container Store
-type ViewDB interface {
-	Snapshot() View
-	Save(*Container) error
-	Delete(*Container) error
-
-	GetByPrefix(string) (string, error)
-
-	ReserveName(name, containerID string) error
-	ReleaseName(name string) error
-}
-
-// View can be used by readers to avoid locking
-type View interface {
-	All() ([]Snapshot, error)
-	Get(id string) (*Snapshot, error)
-
-	GetID(name string) (string, error)
-	GetAllNames() map[string][]string
-}
-
 var schema = &memdb.DBSchema{
 	Tables: map[string]*memdb.TableSchema{
 		memdbContainersTable: {
@@ -128,7 +107,8 @@ var schema = &memdb.DBSchema{
 	},
 }
 
-type memDB struct {
+// ViewDB provides an in-memory transactional (ACID) container store.
+type ViewDB struct {
 	store *memdb.MemDB
 }
 
@@ -144,15 +124,17 @@ func (e NoSuchContainerError) Error() string {
 }
 
 // NewViewDB provides the default implementation, with the default schema
-func NewViewDB() (ViewDB, error) {
+func NewViewDB() (*ViewDB, error) {
 	store, err := memdb.NewMemDB(schema)
 	if err != nil {
 		return nil, err
 	}
-	return &memDB{store: store}, nil
+	return &ViewDB{store: store}, nil
 }
 
-func (db *memDB) GetByPrefix(s string) (string, error) {
+// GetByPrefix returns a container with the given ID prefix. It returns an
+// error if an empty prefix was given or if multiple containers match the prefix.
+func (db *ViewDB) GetByPrefix(s string) (string, error) {
 	if s == "" {
 		return "", ErrEmptyPrefix
 	}
@@ -184,14 +166,14 @@ func (db *memDB) GetByPrefix(s string) (string, error) {
 	return "", ErrNotExist
 }
 
-// Snapshot provides a consistent read-only View of the database
-func (db *memDB) Snapshot() View {
-	return &memdbView{
+// Snapshot provides a consistent read-only view of the database.
+func (db *ViewDB) Snapshot() *View {
+	return &View{
 		txn: db.store.Txn(false),
 	}
 }
 
-func (db *memDB) withTxn(cb func(*memdb.Txn) error) error {
+func (db *ViewDB) withTxn(cb func(*memdb.Txn) error) error {
 	txn := db.store.Txn(true)
 	err := cb(txn)
 	if err != nil {
@@ -204,16 +186,16 @@ func (db *memDB) withTxn(cb func(*memdb.Txn) error) error {
 
 // Save atomically updates the in-memory store state for a Container.
 // Only read only (deep) copies of containers may be passed in.
-func (db *memDB) Save(c *Container) error {
+func (db *ViewDB) Save(c *Container) error {
 	return db.withTxn(func(txn *memdb.Txn) error {
 		return txn.Insert(memdbContainersTable, c)
 	})
 }
 
 // Delete removes an item by ID
-func (db *memDB) Delete(c *Container) error {
+func (db *ViewDB) Delete(c *Container) error {
 	return db.withTxn(func(txn *memdb.Txn) error {
-		view := &memdbView{txn: txn}
+		view := &View{txn: txn}
 		names := view.getNames(c.ID)
 
 		for _, name := range names {
@@ -231,7 +213,7 @@ func (db *memDB) Delete(c *Container) error {
 // ReserveName is idempotent
 // Attempting to reserve a container ID to a name that already exists results in an `ErrNameReserved`
 // A name reservation is globally unique
-func (db *memDB) ReserveName(name, containerID string) error {
+func (db *ViewDB) ReserveName(name, containerID string) error {
 	return db.withTxn(func(txn *memdb.Txn) error {
 		s, err := txn.First(memdbNamesTable, memdbIDIndex, name)
 		if err != nil {
@@ -249,18 +231,19 @@ func (db *memDB) ReserveName(name, containerID string) error {
 
 // ReleaseName releases the reserved name
 // Once released, a name can be reserved again
-func (db *memDB) ReleaseName(name string) error {
+func (db *ViewDB) ReleaseName(name string) error {
 	return db.withTxn(func(txn *memdb.Txn) error {
 		return txn.Delete(memdbNamesTable, nameAssociation{name: name})
 	})
 }
 
-type memdbView struct {
+// View provides a consistent read-only view of the database.
+type View struct {
 	txn *memdb.Txn
 }
 
 // All returns a all items in this snapshot. Returned objects must never be modified.
-func (v *memdbView) All() ([]Snapshot, error) {
+func (v *View) All() ([]Snapshot, error) {
 	var all []Snapshot
 	iter, err := v.txn.Get(memdbContainersTable, memdbIDIndex)
 	if err != nil {
@@ -278,7 +261,7 @@ func (v *memdbView) All() ([]Snapshot, error) {
 }
 
 // Get returns an item by id. Returned objects must never be modified.
-func (v *memdbView) Get(id string) (*Snapshot, error) {
+func (v *View) Get(id string) (*Snapshot, error) {
 	s, err := v.txn.First(memdbContainersTable, memdbIDIndex, id)
 	if err != nil {
 		return nil, err
@@ -290,7 +273,7 @@ func (v *memdbView) Get(id string) (*Snapshot, error) {
 }
 
 // getNames lists all the reserved names for the given container ID.
-func (v *memdbView) getNames(containerID string) []string {
+func (v *View) getNames(containerID string) []string {
 	iter, err := v.txn.Get(memdbNamesTable, memdbContainerIDIndex, containerID)
 	if err != nil {
 		return nil
@@ -309,7 +292,7 @@ func (v *memdbView) getNames(containerID string) []string {
 }
 
 // GetID returns the container ID that the passed in name is reserved to.
-func (v *memdbView) GetID(name string) (string, error) {
+func (v *View) GetID(name string) (string, error) {
 	s, err := v.txn.First(memdbNamesTable, memdbIDIndex, name)
 	if err != nil {
 		return "", err
@@ -321,7 +304,7 @@ func (v *memdbView) GetID(name string) (string, error) {
 }
 
 // GetAllNames returns all registered names.
-func (v *memdbView) GetAllNames() map[string][]string {
+func (v *View) GetAllNames() map[string][]string {
 	iter, err := v.txn.Get(memdbNamesTable, memdbContainerIDIndex)
 	if err != nil {
 		return nil
@@ -342,7 +325,7 @@ func (v *memdbView) GetAllNames() map[string][]string {
 
 // transform maps a (deep) copied Container object to what queries need.
 // A lock on the Container is not held because these are immutable deep copies.
-func (v *memdbView) transform(container *Container) *Snapshot {
+func (v *View) transform(container *Container) *Snapshot {
 	health := types.NoHealthcheck
 	if container.Health != nil {
 		health = container.Health.Status()

+ 1 - 1
container/view_test.go

@@ -373,7 +373,7 @@ func TestTruncIndex(t *testing.T) {
 	}
 }
 
-func assertIndexGet(t *testing.T, snapshot ViewDB, input, expectedResult string, expectError bool) {
+func assertIndexGet(t *testing.T, snapshot *ViewDB, input, expectedResult string, expectError bool) {
 	if result, err := snapshot.GetByPrefix(input); err != nil && !expectError {
 		t.Fatalf("Unexpected error getting '%s': %s", input, err)
 	} else if err == nil && expectError {

+ 1 - 1
daemon/daemon.go

@@ -73,7 +73,7 @@ type Daemon struct {
 	id                    string
 	repository            string
 	containers            container.Store
-	containersReplica     container.ViewDB
+	containersReplica     *container.ViewDB
 	execCommands          *container.ExecStore
 	imageService          ImageService
 	configStore           *config.Config

+ 3 - 3
daemon/list.go

@@ -110,7 +110,7 @@ func (daemon *Daemon) Containers(config *types.ContainerListOptions) ([]*types.C
 	return daemon.reduceContainers(config, daemon.refreshImage)
 }
 
-func (daemon *Daemon) filterByNameIDMatches(view container.View, filter *listContext) ([]container.Snapshot, error) {
+func (daemon *Daemon) filterByNameIDMatches(view *container.View, filter *listContext) ([]container.Snapshot, error) {
 	idSearch := false
 	names := filter.filters.Get("name")
 	ids := filter.filters.Get("id")
@@ -243,7 +243,7 @@ func (daemon *Daemon) reducePsContainer(container *container.Snapshot, filter *l
 }
 
 // foldFilter generates the container filter based on the user's filtering options.
-func (daemon *Daemon) foldFilter(view container.View, config *types.ContainerListOptions) (*listContext, error) {
+func (daemon *Daemon) foldFilter(view *container.View, config *types.ContainerListOptions) (*listContext, error) {
 	ctx := context.TODO()
 	psFilters := config.Filters
 
@@ -363,7 +363,7 @@ func (daemon *Daemon) foldFilter(view container.View, config *types.ContainerLis
 	}, nil
 }
 
-func idOrNameFilter(view container.View, value string) (*container.Snapshot, error) {
+func idOrNameFilter(view *container.View, value string) (*container.Snapshot, error) {
 	filter, err := view.Get(value)
 	switch err.(type) {
 	case container.NoSuchContainerError: