watchable

package module
v0.0.0-...-9bb86f9 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 26, 2022 License: Apache-2.0 Imports: 6 Imported by: 2

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func DeepCopy

func DeepCopy[T any](val T) T

DeepCopy returns a deep copy of a value.

In order of precedence:

  • If the type 'T' has a 'DeepCopy' method (implements the 'DeepCopier[T]' interface), then that method is used.
  • If the type 'T' implements google.golang.org/protobuf/proto.Message, then google.golang.org/protobuf/proto.Clone is used.
  • If the value is a primitive ('bool', any of the 'int' types, either of the 'float' types, either of the 'complex' types, or 'string'), or an array (not slice) or struct that only contains primitives, then it is naively copied by value.

- Otherwise, DeepCopy panics.

func DeepEqual

func DeepEqual[T any](a, b T) bool

DeepEqual returns whether two values are deeply equal.

In order of precedence:

  • If the type 'T' has an 'Equal' method (implements the 'Comparable[T]' interface), then that method is used.
  • If the types of 'a' and 'b' both implement google.golang.org/protobuf/proto.Message, then google.golang.org/protobuf/proto.Equal is used. (This is slightly different than saying "if 'T' implements proto.Message" because it could be that 'T' is an interface type, 'a' and 'b' have differing concrete types, and only one of them implements proto.Message).

- Otherwise, reflect.DeepEqual is used.

Types

type Comparable

type Comparable[T _Comparable[T]] _Comparable[T]

Comparable[T] describes a type 'T' that has an 'Equal(T) bool' method; it is useful for asserting that your Equal method will be accepted by this package's DeepEqual function.

The name of this interface mimics the built-in 'comparable' identifier, deviating from the usual Go naming convention for single-method interfaces ('Equaler').

type DeepCopier

type DeepCopier[T _DeepCopier[T]] _DeepCopier[T]

DeepCopier[T] describes a type 'T' that has a 'DeepCopy() T' method; it is useful for asserting that your DeepCopy method will be accepted by this package's DeepEqual function.

type Map

type Map[K comparable, V any] struct {
	// contains filtered or unexported fields
}

Map[K,V] is a wrapper around map[K]V that is very similar to sync.Map, and that provides the additional features that:

  1. it is thread-safe (compared to a bare map)
  2. it provides type safety (compared to a sync.Map)
  3. it provides a compare-and-swap operation
  4. you can Subscribe to either the whole map or just a subset of the map to watch for updates. This gives you complete snapshots, deltas, and coalescing of rapid updates.

Despite the type parameter for 'V' being 'any', it is not permissible to use any old type; the type must behave correctly in this package's 'DeepCopy' and 'DeepEqual' functions. The type parameter is overly-permissive due to limitations in Go's type system. See the documentation on those functions for more information.

The zero Map[K,V] is empty and ready for use. A Map[K,V] must not be copied after first use.

func (*Map[K, V]) Close

func (tm *Map[K, V]) Close()

Close marks the map as "finished", all subscriber channels are closed and further mutations are forbidden.

After .Close() is called:

  • any attempts to mutate the map (calls to .Store() or .Delete()) will panic;
  • any attempts to read the map (calls to .Load(), .LoadAll(), or .LoadAllMatching()) will continue to work normally; and
  • any calls to .Subscribe() or .SubscribeSubset() will return an already-closed channel.

func (*Map[K, V]) CompareAndSwap

func (tm *Map[K, V]) CompareAndSwap(key K, old, new V) bool

CompareAndSwap is the atomic equivalent of:

if loadedVal, loadedOK := m.Load(key); loadedOK && loadedVal.Equal(old) {
    m.Store(key, new)
    return true
}
return false

func (*Map[K, V]) Delete

func (tm *Map[K, V]) Delete(key K)

Delete deletes the value for a key. This panics if .Close() has already been called.

func (*Map[K, V]) Len

func (tm *Map[K, V]) Len() int

Len returns the number of key/value pairs in the map.

func (*Map[K, V]) Load

func (tm *Map[K, V]) Load(key K) (value V, ok bool)

Load returns a deepcopy of the value for a specific key.

func (*Map[K, V]) LoadAll

func (tm *Map[K, V]) LoadAll() map[K]V

LoadAll returns a deepcopy of all key/value pairs in the map.

func (*Map[K, V]) LoadAllMatching

func (tm *Map[K, V]) LoadAllMatching(include func(K, V) bool) map[K]V

LoadAllMatching returns a deepcopy of all key/value pairs in the map for which the given function returns true. The map is locked during the evaluation of the filter.

func (*Map[K, V]) LoadAndDelete

func (tm *Map[K, V]) LoadAndDelete(key K) (value V, loaded bool)

LoadAndDelete deletes the value for a key, returning a deepcopy of the previous value if any. The 'loaded' result reports whether the key was present.

If the value does need to be deleted, all the same semantics as .Delete() apply.

func (*Map[K, V]) LoadOrStore

func (tm *Map[K, V]) LoadOrStore(key K, val V) (value V, loaded bool)

LoadOrStore returns the existing value for the key if present. Otherwise, it stores and returns the given value. The 'loaded' result is true if the value was loaded, false if stored.

If the value does need to be stored, all the same semantics as .Store() apply.

func (*Map[K, V]) Store

func (tm *Map[K, V]) Store(key K, val V)

Store sets a key sets the value for a key. This panics if .Close() has already been called.

func (*Map[K, V]) Subscribe

func (tm *Map[K, V]) Subscribe(ctx context.Context) <-chan Snapshot[K, V]

Subscribe returns a channel that will emit a complete snapshot of the map immediately after the call to Subscribe(), and then whenever the map changes. Updates are coalesced; if you do not need to worry about reading from the channel faster than you are able. The snapshot will contain the full list of coalesced updates; the initial snapshot will contain 0 updates. A read from the channel will block as long as there are no changes since the last read.

The values in the snapshot are deepcopies of the actual values in the map, but values may be reused between snapshots; if you mutate a value in a snapshot, that mutation may erroneously persist in future snapshots.

The returned channel will be closed when the Context is Done, or .Close() is called. If .Close() has already been called, then an already-closed channel is returned.

func (*Map[K, V]) SubscribeSubset

func (tm *Map[K, V]) SubscribeSubset(ctx context.Context, include func(K, V) bool) <-chan Snapshot[K, V]

SubscribeSubset is like Subscribe, but the snapshot returned only includes entries that satisfy the 'include' predicate. Mutations to entries that don't satisfy the predicate do not cause a new snapshot to be emitted. If the value for a key changes from satisfying the predicate to not satisfying it, then this is treated as a delete operation, and a new snapshot is generated.

type Snapshot

type Snapshot[K comparable, V any] struct {
	// State is the current state of the snapshot.
	State map[K]V
	// Updates is the list of mutations that have happened since the previous snapshot.
	// Mutations that delete a value have .Delete=true, and .Value set to the value that was
	// deleted.  No-op updates are not included (i.e., setting something to its current value,
	// or deleting something that does not exist).
	Updates []Update[K, V]
}

Snapshot contains a snapshot of the current state of a Map, as well as a list of changes that have happened since the last snapshot.

type Update

type Update[K comparable, V any] struct {
	Key    K
	Delete bool // Whether this is deleting the entry for .Key, or setting it to .Value.
	Value  V
}

Update describes a mutation made to a Map.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL