xref: /aosp_15_r20/external/licenseclassifier/stringclassifier/internal/pq/priority.go (revision 46c4c49da23cae783fa41bf46525a6505638499a)
1*46c4c49dSIbrahim Kanouche// Copyright 2017 Google Inc.
2*46c4c49dSIbrahim Kanouche//
3*46c4c49dSIbrahim Kanouche// Licensed under the Apache License, Version 2.0 (the "License");
4*46c4c49dSIbrahim Kanouche// you may not use this file except in compliance with the License.
5*46c4c49dSIbrahim Kanouche// You may obtain a copy of the License at
6*46c4c49dSIbrahim Kanouche//
7*46c4c49dSIbrahim Kanouche//     http://www.apache.org/licenses/LICENSE-2.0
8*46c4c49dSIbrahim Kanouche//
9*46c4c49dSIbrahim Kanouche// Unless required by applicable law or agreed to in writing, software
10*46c4c49dSIbrahim Kanouche// distributed under the License is distributed on an "AS IS" BASIS,
11*46c4c49dSIbrahim Kanouche// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12*46c4c49dSIbrahim Kanouche// See the License for the specific language governing permissions and
13*46c4c49dSIbrahim Kanouche// limitations under the License.
14*46c4c49dSIbrahim Kanouche
15*46c4c49dSIbrahim Kanouche// Package pq provides a priority queue.
16*46c4c49dSIbrahim Kanouchepackage pq
17*46c4c49dSIbrahim Kanouche
18*46c4c49dSIbrahim Kanoucheimport "container/heap"
19*46c4c49dSIbrahim Kanouche
20*46c4c49dSIbrahim Kanouche// NewQueue returns an unbounded priority queue that compares elements using
21*46c4c49dSIbrahim Kanouche// less; the minimal element is at the top of the queue.
22*46c4c49dSIbrahim Kanouche//
23*46c4c49dSIbrahim Kanouche// If setIndex is not nil, the queue calls setIndex to inform each element of
24*46c4c49dSIbrahim Kanouche// its position in the queue.  If an element's priority changes, its position in
25*46c4c49dSIbrahim Kanouche// the queue may be incorrect.  Call Fix on the element's index to update the
26*46c4c49dSIbrahim Kanouche// queue.  Call Remove on the element's index to remove it from the queue.
27*46c4c49dSIbrahim Kanouchefunc NewQueue(less func(x, y interface{}) bool, setIndex func(x interface{}, idx int)) *Queue {
28*46c4c49dSIbrahim Kanouche	return &Queue{
29*46c4c49dSIbrahim Kanouche		heap: pqHeap{
30*46c4c49dSIbrahim Kanouche			less:     less,
31*46c4c49dSIbrahim Kanouche			setIndex: setIndex,
32*46c4c49dSIbrahim Kanouche		},
33*46c4c49dSIbrahim Kanouche	}
34*46c4c49dSIbrahim Kanouche}
35*46c4c49dSIbrahim Kanouche
36*46c4c49dSIbrahim Kanouche// Queue is a priority queue that supports updating the priority of an element.
37*46c4c49dSIbrahim Kanouche// A Queue must be created with NewQueue.
38*46c4c49dSIbrahim Kanouchetype Queue struct {
39*46c4c49dSIbrahim Kanouche	heap pqHeap
40*46c4c49dSIbrahim Kanouche}
41*46c4c49dSIbrahim Kanouche
42*46c4c49dSIbrahim Kanouche// Len returns the number of elements in the queue.
43*46c4c49dSIbrahim Kanouchefunc (pq *Queue) Len() int {
44*46c4c49dSIbrahim Kanouche	return pq.heap.Len()
45*46c4c49dSIbrahim Kanouche}
46*46c4c49dSIbrahim Kanouche
47*46c4c49dSIbrahim Kanouche// Push adds x to the queue.
48*46c4c49dSIbrahim Kanouchefunc (pq *Queue) Push(x interface{}) {
49*46c4c49dSIbrahim Kanouche	heap.Push(&pq.heap, x)
50*46c4c49dSIbrahim Kanouche}
51*46c4c49dSIbrahim Kanouche
52*46c4c49dSIbrahim Kanouche// Min returns the minimal element.
53*46c4c49dSIbrahim Kanouche// Min panics if the queue is empty.
54*46c4c49dSIbrahim Kanouchefunc (pq *Queue) Min() interface{} {
55*46c4c49dSIbrahim Kanouche	return pq.heap.a[0]
56*46c4c49dSIbrahim Kanouche}
57*46c4c49dSIbrahim Kanouche
58*46c4c49dSIbrahim Kanouche// Pop removes and returns the minimal element.
59*46c4c49dSIbrahim Kanouche// Pop panics if the queue is empty.
60*46c4c49dSIbrahim Kanouchefunc (pq *Queue) Pop() interface{} {
61*46c4c49dSIbrahim Kanouche	return heap.Pop(&pq.heap)
62*46c4c49dSIbrahim Kanouche}
63*46c4c49dSIbrahim Kanouche
64*46c4c49dSIbrahim Kanouche// Fix adjusts the heap to reflect that the element at index has changed priority.
65*46c4c49dSIbrahim Kanouchefunc (pq *Queue) Fix(index int) {
66*46c4c49dSIbrahim Kanouche	heap.Fix(&pq.heap, index)
67*46c4c49dSIbrahim Kanouche}
68*46c4c49dSIbrahim Kanouche
69*46c4c49dSIbrahim Kanouche// Remove removes the element at index i from the heap.
70*46c4c49dSIbrahim Kanouchefunc (pq *Queue) Remove(index int) {
71*46c4c49dSIbrahim Kanouche	heap.Remove(&pq.heap, index)
72*46c4c49dSIbrahim Kanouche}
73*46c4c49dSIbrahim Kanouche
74*46c4c49dSIbrahim Kanouche// pqHeap implements heap.Interface.
75*46c4c49dSIbrahim Kanouchetype pqHeap struct {
76*46c4c49dSIbrahim Kanouche	a        []interface{}
77*46c4c49dSIbrahim Kanouche	less     func(x, y interface{}) bool
78*46c4c49dSIbrahim Kanouche	setIndex func(x interface{}, idx int)
79*46c4c49dSIbrahim Kanouche}
80*46c4c49dSIbrahim Kanouche
81*46c4c49dSIbrahim Kanouchefunc (h pqHeap) Len() int {
82*46c4c49dSIbrahim Kanouche	return len(h.a)
83*46c4c49dSIbrahim Kanouche}
84*46c4c49dSIbrahim Kanouche
85*46c4c49dSIbrahim Kanouchefunc (h pqHeap) Less(i, j int) bool {
86*46c4c49dSIbrahim Kanouche	return h.less(h.a[i], h.a[j])
87*46c4c49dSIbrahim Kanouche}
88*46c4c49dSIbrahim Kanouche
89*46c4c49dSIbrahim Kanouchefunc (h pqHeap) Swap(i, j int) {
90*46c4c49dSIbrahim Kanouche	h.a[i], h.a[j] = h.a[j], h.a[i]
91*46c4c49dSIbrahim Kanouche	if h.setIndex != nil {
92*46c4c49dSIbrahim Kanouche		h.setIndex(h.a[i], i)
93*46c4c49dSIbrahim Kanouche		h.setIndex(h.a[j], j)
94*46c4c49dSIbrahim Kanouche	}
95*46c4c49dSIbrahim Kanouche}
96*46c4c49dSIbrahim Kanouche
97*46c4c49dSIbrahim Kanouchefunc (h *pqHeap) Push(x interface{}) {
98*46c4c49dSIbrahim Kanouche	n := len(h.a)
99*46c4c49dSIbrahim Kanouche	if h.setIndex != nil {
100*46c4c49dSIbrahim Kanouche		h.setIndex(x, n)
101*46c4c49dSIbrahim Kanouche	}
102*46c4c49dSIbrahim Kanouche	h.a = append(h.a, x)
103*46c4c49dSIbrahim Kanouche}
104*46c4c49dSIbrahim Kanouche
105*46c4c49dSIbrahim Kanouchefunc (h *pqHeap) Pop() interface{} {
106*46c4c49dSIbrahim Kanouche	old := h.a
107*46c4c49dSIbrahim Kanouche	n := len(old)
108*46c4c49dSIbrahim Kanouche	x := old[n-1]
109*46c4c49dSIbrahim Kanouche	h.a = old[:n-1]
110*46c4c49dSIbrahim Kanouche	return x
111*46c4c49dSIbrahim Kanouche}
112