github.com/docker/compose-on-kubernetes@v0.5.0/internal/deduplication/stringchannel.go (about)

     1  package deduplication
     2  
     3  import "sync"
     4  
     5  // StringChan is a deduplicating string channel
     6  type StringChan struct {
     7  	mut     sync.Mutex
     8  	content map[string]struct{}
     9  	ch      chan string
    10  	input   chan string
    11  	output  chan string
    12  }
    13  
    14  // NewStringChan creates a StringChan with the specified buffer size
    15  func NewStringChan(bufferSize int) *StringChan {
    16  	result := &StringChan{ch: make(chan string, bufferSize), content: make(map[string]struct{}, bufferSize+1), input: make(chan string), output: make(chan string)}
    17  	go func() {
    18  		defer close(result.ch)
    19  		for v := range result.input {
    20  			result.push(v)
    21  		}
    22  	}()
    23  	go func() {
    24  		defer close(result.output)
    25  		for {
    26  			v, ok := result.pull()
    27  			if !ok {
    28  				return
    29  			}
    30  			result.output <- v
    31  		}
    32  	}()
    33  	return result
    34  }
    35  
    36  // Close releases all resources
    37  func (c *StringChan) Close() {
    38  	close(c.input)
    39  }
    40  
    41  // Push pushes a value if it is not in the buffer
    42  func (c *StringChan) push(v string) {
    43  	added := func() bool {
    44  		c.mut.Lock()
    45  		defer c.mut.Unlock()
    46  		if _, ok := c.content[v]; ok {
    47  			return false
    48  		}
    49  		c.content[v] = struct{}{}
    50  		return true
    51  	}()
    52  	if added {
    53  		c.ch <- v
    54  	}
    55  }
    56  
    57  // Pull consumes a value
    58  func (c *StringChan) pull() (string, bool) {
    59  	v, ok := <-c.ch
    60  	c.mut.Lock()
    61  	defer c.mut.Unlock()
    62  	delete(c.content, v)
    63  	return v, ok
    64  }
    65  
    66  // In returns the input channel of the deduplicator
    67  func (c *StringChan) In() chan<- string {
    68  	return c.input
    69  }
    70  
    71  // Out returns the output channel of the deduplicator
    72  func (c *StringChan) Out() <-chan string {
    73  	return c.output
    74  }