Quellcode durchsuchen

container: remove ViewDB and View interfaces, use concrete types

These interfaces were added in aacddda89df05b88a6d15fb33c42864760385ab2, with
no clear motivation, other than "Also hide ViewDB behind an interface".

This patch removes the interface in favor of using a concrete implementation;
There's currently only one implementation of this interface, and if we would
decide to change to an alternative implementation, we could define relevant
interfaces on the receiver side.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Sebastiaan van Stijn vor 2 Jahren
Ursprung
Commit
511a909ae6
5 geänderte Dateien mit 30 neuen und 47 gelöschten Zeilen
  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: