github.com/anchore/syft@v1.4.2-0.20240516191711-1bec1fc5d397/internal/task/set.go (about)

     1  package task
     2  
     3  type set struct {
     4  	order []string
     5  	tasks map[string]Task
     6  }
     7  
     8  func newSet(tasks ...Task) *set {
     9  	s := &set{
    10  		order: []string{},
    11  		tasks: make(map[string]Task),
    12  	}
    13  
    14  	s.Add(tasks...)
    15  
    16  	return s
    17  }
    18  
    19  func (ts *set) Len() int {
    20  	return len(ts.tasks)
    21  }
    22  
    23  func (ts *set) Add(tasks ...Task) {
    24  	for _, t := range tasks {
    25  		taskName := t.Name()
    26  		if _, exists := ts.tasks[taskName]; exists {
    27  			continue
    28  		}
    29  		ts.tasks[taskName] = t
    30  		ts.order = append(ts.order, taskName)
    31  	}
    32  }
    33  
    34  func (ts *set) Remove(tasks ...Task) {
    35  	for _, t := range tasks {
    36  		taskName := t.Name()
    37  		if _, exists := ts.tasks[taskName]; !exists {
    38  			continue
    39  		}
    40  
    41  		delete(ts.tasks, taskName)
    42  		for i, t := range ts.order {
    43  			if t == taskName {
    44  				ts.order = append(ts.order[:i], ts.order[i+1:]...)
    45  				break
    46  			}
    47  		}
    48  	}
    49  }
    50  
    51  func (ts *set) Intersect(tasks ...Task) {
    52  	other := newSet(tasks...)
    53  	result := newSet()
    54  	for _, taskName := range ts.order {
    55  		// we make a new set to prevent the original set from being modified while we are iterating over "order"
    56  		if _, exists := other.tasks[taskName]; exists {
    57  			// note: keep the original task and ordering
    58  			result.Add(ts.tasks[taskName])
    59  		}
    60  	}
    61  	*ts = *result
    62  }
    63  
    64  func (ts set) Tasks() tasks {
    65  	var result []Task
    66  	for _, name := range ts.order {
    67  		result = append(result, ts.tasks[name])
    68  	}
    69  	return result
    70  }