github.com/benz9527/toy-box/algo@v0.0.0-20240221120937-66c0c6bd5abd/queue/priority_queue_test.go (about)

     1  package queue
     2  
     3  import (
     4  	"fmt"
     5  	"github.com/stretchr/testify/assert"
     6  	"testing"
     7  	"unsafe"
     8  )
     9  
    10  type person struct {
    11  	name   string
    12  	age    int
    13  	salary int64
    14  }
    15  
    16  func TestPriorityQueueItemAlignmentAndSize(t *testing.T) {
    17  	item := NewPQItem[*person](&person{age: 10, name: "p0"}, 1)
    18  	t.Logf("item alignment size: %d\n", unsafe.Alignof(item))
    19  	prototype := item.(*pqItem[*person])
    20  	t.Logf("item prototype alignment size: %d\n", unsafe.Alignof(prototype))
    21  	t.Logf("item prototype value alignment size: %d\n", unsafe.Alignof(prototype.value))
    22  	t.Logf("item prototype priority alignment size: %d\n", unsafe.Alignof(prototype.priority))
    23  	t.Logf("item prototype index alignment size: %d\n", unsafe.Alignof(prototype.index))
    24  	t.Logf("item prototype comparator alignment size: %d\n", unsafe.Alignof(prototype.comparator))
    25  	t.Logf("item prototype size: %d\n", unsafe.Sizeof(prototype))
    26  	t.Logf("item prototype value size: %d\n", unsafe.Sizeof(prototype.value))
    27  	t.Logf("item prototype priority size: %d\n", unsafe.Sizeof(prototype.priority))
    28  	t.Logf("item prototype index size: %d\n", unsafe.Sizeof(prototype.index))
    29  	t.Logf("item prototype comparator size: %d\n", unsafe.Sizeof(prototype.comparator))
    30  }
    31  
    32  func TestPriorityQueue_MinValueAsHighPriority(t *testing.T) {
    33  	pq := NewArrayPriorityQueue[*person](32,
    34  		func(i, j PQItem[*person]) bool {
    35  			return i.GetPriority() < j.GetPriority()
    36  		},
    37  	)
    38  	pq.Push(NewPQItem[*person](&person{age: 10, name: "p0"}, 1))
    39  	pq.Push(NewPQItem[*person](&person{age: 101, name: "p1"}, 101))
    40  	pq.Push(NewPQItem[*person](&person{age: 10, name: "p2"}, 10))
    41  	pq.Push(NewPQItem[*person](&person{age: 200, name: "p3"}, 200))
    42  	pq.Push(NewPQItem[*person](&person{age: 3, name: "p4"}, 3))
    43  	pq.Push(NewPQItem[*person](&person{age: 1, name: "p5"}, 1))
    44  	pq.Push(NewPQItem[*person](&person{age: 5, name: "p6"}, 5))
    45  
    46  	expectedPriorities := []int64{1, 1, 3, 5, 10, 101, 200}
    47  	for i, priority := range expectedPriorities {
    48  		item := pq.Pop()
    49  		t.Logf("%v, priority: %d", item.GetValue(), item.GetPriority())
    50  		assert.Equal(t, priority, item.GetPriority(), "priority", i)
    51  	}
    52  }
    53  
    54  func TestPriorityQueue_MaxValueAsHighPriority(t *testing.T) {
    55  	pq := NewArrayPriorityQueue[*person](32,
    56  		func(i, j PQItem[*person]) bool {
    57  			return i.GetPriority() > j.GetPriority()
    58  		},
    59  	)
    60  	pq.Push(NewPQItem[*person](&person{age: 10, name: "p0"}, 1))
    61  	pq.Push(NewPQItem[*person](&person{age: 101, name: "p1"}, 101))
    62  	pq.Push(NewPQItem[*person](&person{age: 10, name: "p2"}, 10))
    63  	pq.Push(NewPQItem[*person](&person{age: 200, name: "p3"}, 200))
    64  	pq.Push(NewPQItem[*person](&person{age: 3, name: "p4"}, 3))
    65  	pq.Push(NewPQItem[*person](&person{age: 1, name: "p5"}, 1))
    66  	pq.Push(NewPQItem[*person](&person{age: 5, name: "p6"}, 5))
    67  	pq.Push(NewPQItem[*person](&person{age: 200, name: "p7"}, 201))
    68  
    69  	expectedPriorities := []int64{201, 200, 101, 10, 5, 3, 1, 1}
    70  	for i, priority := range expectedPriorities {
    71  		item := pq.Pop()
    72  		t.Logf("%v, priority: %d", item.GetValue(), item.GetPriority())
    73  		assert.Equal(t, priority, item.GetPriority(), "priority", i)
    74  	}
    75  }
    76  
    77  func TestPriorityQueue_MaxValueAsHighPriority_Peek(t *testing.T) {
    78  	pq := NewArrayPriorityQueue[*person](32,
    79  		func(i, j PQItem[*person]) bool {
    80  			return i.GetPriority() > j.GetPriority()
    81  		},
    82  	)
    83  	pq.Push(NewPQItem[*person](&person{age: 10, name: "p0"}, 1))
    84  	pq.Push(NewPQItem[*person](&person{age: 101, name: "p1"}, 101))
    85  	pq.Push(NewPQItem[*person](&person{age: 10, name: "p2"}, 10))
    86  	pq.Push(NewPQItem[*person](&person{age: 200, name: "p3"}, 200))
    87  	pq.Push(NewPQItem[*person](&person{age: 3, name: "p4"}, 3))
    88  	pq.Push(NewPQItem[*person](&person{age: 1, name: "p5"}, 1))
    89  	pq.Push(NewPQItem[*person](&person{age: 5, name: "p6"}, 5))
    90  	pq.Push(NewPQItem[*person](&person{age: 200, name: "p7"}, 201))
    91  
    92  	expectedPriorities := []int64{201, 200, 101, 10, 5, 3, 1, 1}
    93  	for i, priority := range expectedPriorities {
    94  		peekItem := pq.Peek()
    95  		t.Logf("peek item: %v, priority: %d", peekItem.GetValue(), peekItem.GetPriority())
    96  		item := pq.Pop()
    97  		t.Logf("%v, priority: %d", item.GetValue(), item.GetPriority())
    98  		assert.Equal(t, priority, item.GetPriority(), "priority", i)
    99  	}
   100  }
   101  
   102  // goos: linux
   103  // goarch: amd64
   104  // pkg: github.com/benz9527/toy-box/algo/queue
   105  // cpu: Intel(R) Core(TM) i5-4590 CPU @ 3.30GHz
   106  // BenchmarkPriorityQueue_Push
   107  // BenchmarkPriorityQueue_Push-4   	 4362896	       229.8 ns/op	      96 B/op	       0 allocs/op
   108  func BenchmarkPriorityQueue_Push(b *testing.B) {
   109  	var list = make([]PQItem[*person], 0, b.N)
   110  	for i := 0; i < b.N; i++ {
   111  		e := NewPQItem[*person](&person{age: i, name: fmt.Sprintf("p%d", i)}, int64(i))
   112  		list = append(list, e)
   113  	}
   114  	b.ResetTimer()
   115  	pq := NewArrayPriorityQueue[*person](32,
   116  		func(i, j PQItem[*person]) bool {
   117  			return i.GetPriority() < j.GetPriority()
   118  		},
   119  	)
   120  	for i := 0; i < b.N; i++ {
   121  		pq.Push(list[i])
   122  	}
   123  	b.ReportAllocs()
   124  }
   125  
   126  // goos: linux
   127  // goarch: amd64
   128  // pkg: github.com/benz9527/toy-box/algo/queue
   129  // cpu: Intel(R) Core(TM) i5-4590 CPU @ 3.30GHz
   130  // BenchmarkPriorityQueue_Pop
   131  // BenchmarkPriorityQueue_Pop-4   	  818748	      2113 ns/op	       0 B/op	       0 allocs/op
   132  func BenchmarkPriorityQueue_Pop(b *testing.B) {
   133  	var list = make([]PQItem[*person], 0, b.N)
   134  	for i := 0; i < b.N; i++ {
   135  		e := NewPQItem[*person](&person{age: i, name: fmt.Sprintf("p%d", i)}, int64(i))
   136  		list = append(list, e)
   137  	}
   138  	pq := NewArrayPriorityQueue[*person](32)
   139  	for i := 0; i < b.N; i++ {
   140  		pq.Push(list[i])
   141  	}
   142  	b.ResetTimer()
   143  	for i := 0; i < b.N; i++ {
   144  		_ = pq.Pop()
   145  	}
   146  	b.ReportAllocs()
   147  }