github.com/google/osv-scalibr@v0.4.1/enricher/reachability/java/uniqueq.go (about)

     1  // Copyright 2025 Google LLC
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //      http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package java
    16  
    17  type pair[K, V comparable] struct {
    18  	first  K
    19  	second V
    20  }
    21  
    22  // UniqueQueue is a queue data structure that will add keys at most once in its
    23  // lifetime. Duplicate keys are ignored when pushing them.
    24  type UniqueQueue[K, V comparable] struct {
    25  	seen map[K]struct{}
    26  	q    []pair[K, V]
    27  }
    28  
    29  // NewQueue creates a new UniqueQueue.
    30  func NewQueue[K, V comparable](seen map[K]struct{}) *UniqueQueue[K, V] {
    31  	return &UniqueQueue[K, V]{
    32  		seen: seen,
    33  	}
    34  }
    35  
    36  // Push adds a key and its value to the queue. If the key is already in the queue,
    37  // it will be ignored. It returns true if the key was added, false otherwise.
    38  func (q *UniqueQueue[K, V]) Push(key K, value V) bool {
    39  	if _, ok := q.seen[key]; ok {
    40  		return false
    41  	}
    42  	q.seen[key] = struct{}{}
    43  	q.q = append(q.q, pair[K, V]{key, value})
    44  
    45  	return true
    46  }
    47  
    48  // Seen returns true if the key is already in the queue.
    49  func (q *UniqueQueue[K, V]) Seen(key K) bool {
    50  	_, ok := q.seen[key]
    51  
    52  	return ok
    53  }
    54  
    55  // Pop removes the first key and value from the queue.
    56  func (q *UniqueQueue[K, V]) Pop() (K, V) {
    57  	item := q.q[0]
    58  	q.q = q.q[1:]
    59  
    60  	return item.first, item.second
    61  }
    62  
    63  // Empty returns true if the queue is empty.
    64  func (q *UniqueQueue[K, V]) Empty() bool {
    65  	return len(q.q) == 0
    66  }