github.com/angenalZZZ/gofunc@v0.0.0-20210507121333-48ff1be3917b/data/queue/priority_queue_test.go (about)

     1  package queue
     2  
     3  import (
     4  	"fmt"
     5  	"math"
     6  	"os"
     7  	"testing"
     8  	"time"
     9  )
    10  
    11  func TestPriorityQueueClose(t *testing.T) {
    12  	file := fmt.Sprintf("test_db_%d", time.Now().UnixNano())
    13  	pq, err := OpenPriorityQueue(file, ASC)
    14  	if err != nil {
    15  		t.Error(err)
    16  	}
    17  	defer pq.Drop()
    18  
    19  	for p := 0; p <= 4; p++ {
    20  		for i := 1; i <= 10; i++ {
    21  			if _, err = pq.EnqueueString(uint8(p), fmt.Sprintf("value for item %d", i)); err != nil {
    22  				t.Error(err)
    23  			}
    24  		}
    25  	}
    26  
    27  	if pq.Length() != 50 {
    28  		t.Errorf("Expected queue length of 1, got %d", pq.Length())
    29  	}
    30  
    31  	pq.Close()
    32  
    33  	if _, err = pq.Dequeue(); err != ErrDBClosed {
    34  		t.Errorf("Expected to get database closed error, got %s", err.Error())
    35  	}
    36  
    37  	if pq.Length() != 0 {
    38  		t.Errorf("Expected queue length of 0, got %d", pq.Length())
    39  	}
    40  }
    41  
    42  func TestPriorityQueueDrop(t *testing.T) {
    43  	file := fmt.Sprintf("test_db_%d", time.Now().UnixNano())
    44  	pq, err := OpenPriorityQueue(file, ASC)
    45  	if err != nil {
    46  		t.Error(err)
    47  	}
    48  
    49  	if _, err = os.Stat(file); os.IsNotExist(err) {
    50  		t.Error(err)
    51  	}
    52  
    53  	pq.Drop()
    54  
    55  	if _, err = os.Stat(file); err == nil {
    56  		t.Error("Expected directory for test database to have been deleted")
    57  	}
    58  }
    59  
    60  func TestPriorityQueueIncompatibleType(t *testing.T) {
    61  	file := fmt.Sprintf("test_db_%d", time.Now().UnixNano())
    62  	q, err := OpenQueue(file)
    63  	if err != nil {
    64  		t.Error(err)
    65  	}
    66  	defer q.Drop()
    67  	q.Close()
    68  
    69  	if _, err = OpenPriorityQueue(file, ASC); err != ErrIncompatibleType {
    70  		t.Error("Expected priority queue to return ErrIncompatibleTypes when opening Queue")
    71  	}
    72  }
    73  
    74  func TestPriorityQueueEnqueue(t *testing.T) {
    75  	file := fmt.Sprintf("test_db_%d", time.Now().UnixNano())
    76  	pq, err := OpenPriorityQueue(file, ASC)
    77  	if err != nil {
    78  		t.Error(err)
    79  	}
    80  	defer pq.Drop()
    81  
    82  	for p := 0; p <= 4; p++ {
    83  		for i := 1; i <= 10; i++ {
    84  			if _, err = pq.EnqueueString(uint8(p), fmt.Sprintf("value for item %d", i)); err != nil {
    85  				t.Error(err)
    86  			}
    87  		}
    88  	}
    89  
    90  	if pq.Length() != 50 {
    91  		t.Errorf("Expected queue size of 50, got %d", pq.Length())
    92  	}
    93  }
    94  
    95  func TestPriorityQueueDequeueAsc(t *testing.T) {
    96  	file := fmt.Sprintf("test_db_%d", time.Now().UnixNano())
    97  	pq, err := OpenPriorityQueue(file, ASC)
    98  	if err != nil {
    99  		t.Error(err)
   100  	}
   101  	defer pq.Drop()
   102  
   103  	for p := 0; p <= 4; p++ {
   104  		for i := 1; i <= 10; i++ {
   105  			if _, err = pq.EnqueueString(uint8(p), fmt.Sprintf("value for item %d", i)); err != nil {
   106  				t.Error(err)
   107  			}
   108  		}
   109  	}
   110  
   111  	if pq.Length() != 50 {
   112  		t.Errorf("Expected queue length of 1, got %d", pq.Length())
   113  	}
   114  
   115  	deqItem, err := pq.Dequeue()
   116  	if err != nil {
   117  		t.Error(err)
   118  	}
   119  
   120  	if pq.Length() != 49 {
   121  		t.Errorf("Expected queue length of 49, got %d", pq.Length())
   122  	}
   123  
   124  	compStr := "value for item 1"
   125  
   126  	if deqItem.Priority != 0 {
   127  		t.Errorf("Expected priority level to be 0, got %d", deqItem.Priority)
   128  	}
   129  
   130  	if deqItem.ToString() != compStr {
   131  		t.Errorf("Expected string to be '%s', got '%s'", compStr, deqItem.ToString())
   132  	}
   133  }
   134  
   135  func TestPriorityQueueDequeueDesc(t *testing.T) {
   136  	file := fmt.Sprintf("test_db_%d", time.Now().UnixNano())
   137  	pq, err := OpenPriorityQueue(file, DESC)
   138  	if err != nil {
   139  		t.Error(err)
   140  	}
   141  	defer pq.Drop()
   142  
   143  	for p := 0; p <= 4; p++ {
   144  		for i := 1; i <= 10; i++ {
   145  			if _, err = pq.EnqueueString(uint8(p), fmt.Sprintf("value for item %d", i)); err != nil {
   146  				t.Error(err)
   147  			}
   148  		}
   149  	}
   150  
   151  	if pq.Length() != 50 {
   152  		t.Errorf("Expected queue length of 1, got %d", pq.Length())
   153  	}
   154  
   155  	deqItem, err := pq.Dequeue()
   156  	if err != nil {
   157  		t.Error(err)
   158  	}
   159  
   160  	if pq.Length() != 49 {
   161  		t.Errorf("Expected queue length of 49, got %d", pq.Length())
   162  	}
   163  
   164  	compStr := "value for item 1"
   165  
   166  	if deqItem.Priority != 4 {
   167  		t.Errorf("Expected priority level to be 4, got %d", deqItem.Priority)
   168  	}
   169  
   170  	if deqItem.ToString() != compStr {
   171  		t.Errorf("Expected string to be '%s', got '%s'", compStr, deqItem.ToString())
   172  	}
   173  }
   174  
   175  func TestPriorityQueueDequeueByPriority(t *testing.T) {
   176  	file := fmt.Sprintf("test_db_%d", time.Now().UnixNano())
   177  	pq, err := OpenPriorityQueue(file, ASC)
   178  	if err != nil {
   179  		t.Error(err)
   180  	}
   181  	defer pq.Drop()
   182  
   183  	for p := 0; p <= 4; p++ {
   184  		for i := 1; i <= 10; i++ {
   185  			if _, err = pq.EnqueueString(uint8(p), fmt.Sprintf("value for item %d", i)); err != nil {
   186  				t.Error(err)
   187  			}
   188  		}
   189  	}
   190  
   191  	if pq.Length() != 50 {
   192  		t.Errorf("Expected queue length of 50, got %d", pq.Length())
   193  	}
   194  
   195  	deqItem, err := pq.DequeueByPriority(3)
   196  	if err != nil {
   197  		t.Error(err)
   198  	}
   199  
   200  	if pq.Length() != 49 {
   201  		t.Errorf("Expected queue length of 49, got %d", pq.Length())
   202  	}
   203  
   204  	compStr := "value for item 1"
   205  
   206  	if deqItem.Priority != 3 {
   207  		t.Errorf("Expected priority level to be 1, got %d", deqItem.Priority)
   208  	}
   209  
   210  	if deqItem.ToString() != compStr {
   211  		t.Errorf("Expected string to be '%s', got '%s'", compStr, deqItem.ToString())
   212  	}
   213  }
   214  
   215  func TestPriorityQueueEncodeDecodePointerJSON(t *testing.T) {
   216  	file := fmt.Sprintf("test_db_%d", time.Now().UnixNano())
   217  	pq, err := OpenPriorityQueue(file, DESC)
   218  	if err != nil {
   219  		t.Error(err)
   220  	}
   221  	defer pq.Drop()
   222  
   223  	type subObject struct {
   224  		Value *int
   225  	}
   226  
   227  	type object struct {
   228  		Value     int
   229  		SubObject subObject
   230  	}
   231  
   232  	val := 0
   233  	obj := object{
   234  		Value: 0,
   235  		SubObject: subObject{
   236  			Value: &val,
   237  		},
   238  	}
   239  
   240  	if _, err = pq.EnqueueObjectAsJSON(0, obj); err != nil {
   241  		t.Error(err)
   242  	}
   243  
   244  	item, err := pq.Dequeue()
   245  	if err != nil {
   246  		t.Error(err)
   247  	}
   248  
   249  	var itemObj object
   250  	if err := item.ToObjectFromJSON(&itemObj); err != nil {
   251  		t.Error(err)
   252  	}
   253  
   254  	if *itemObj.SubObject.Value != 0 {
   255  		t.Errorf("Expected object subobject value to be '0', got '%v'", *itemObj.SubObject.Value)
   256  	}
   257  }
   258  
   259  func TestPriorityQueuePeek(t *testing.T) {
   260  	file := fmt.Sprintf("test_db_%d", time.Now().UnixNano())
   261  	pq, err := OpenPriorityQueue(file, ASC)
   262  	if err != nil {
   263  		t.Error(err)
   264  	}
   265  	defer pq.Drop()
   266  
   267  	for p := 0; p <= 4; p++ {
   268  		for i := 1; i <= 10; i++ {
   269  			if _, err = pq.EnqueueString(uint8(p), fmt.Sprintf("value for item %d", i)); err != nil {
   270  				t.Error(err)
   271  			}
   272  		}
   273  	}
   274  
   275  	compStr := "value for item 1"
   276  
   277  	peekItem, err := pq.Peek()
   278  	if err != nil {
   279  		t.Error(err)
   280  	}
   281  
   282  	if peekItem.Priority != 0 {
   283  		t.Errorf("Expected priority level to be 0, got %d", peekItem.Priority)
   284  	}
   285  
   286  	if peekItem.ToString() != compStr {
   287  		t.Errorf("Expected string to be '%s', got '%s'", compStr, peekItem.ToString())
   288  	}
   289  
   290  	if pq.Length() != 50 {
   291  		t.Errorf("Expected queue length of 50, got %d", pq.Length())
   292  	}
   293  }
   294  
   295  func TestPriorityQueuePeekByOffsetEmptyAsc(t *testing.T) {
   296  	file := fmt.Sprintf("test_db_%d", time.Now().UnixNano())
   297  	pq, err := OpenPriorityQueue(file, ASC)
   298  	if err != nil {
   299  		t.Error(err)
   300  	}
   301  	defer pq.Drop()
   302  
   303  	_, err = pq.PeekByOffset(0)
   304  	if err != ErrEmpty {
   305  		t.Errorf("Expected to get empty error, got %s", err.Error())
   306  	}
   307  
   308  	if _, err = pq.EnqueueString(0, "value"); err != nil {
   309  		t.Error(err)
   310  	}
   311  
   312  	_, err = pq.PeekByOffset(0)
   313  	if err != nil {
   314  		t.Errorf("Expected to get nil error, got %s", err.Error())
   315  	}
   316  
   317  	if _, err = pq.Dequeue(); err != nil {
   318  		t.Error(err)
   319  	}
   320  
   321  	_, err = pq.PeekByOffset(0)
   322  	if err != ErrEmpty {
   323  		t.Errorf("Expected to get empty error, got %s", err.Error())
   324  	}
   325  }
   326  
   327  func TestPriorityQueuePeekByOffsetEmptyDesc(t *testing.T) {
   328  	file := fmt.Sprintf("test_db_%d", time.Now().UnixNano())
   329  	pq, err := OpenPriorityQueue(file, DESC)
   330  	if err != nil {
   331  		t.Error(err)
   332  	}
   333  	defer pq.Drop()
   334  
   335  	_, err = pq.PeekByOffset(0)
   336  	if err != ErrEmpty {
   337  		t.Errorf("Expected to get empty error, got %s", err.Error())
   338  	}
   339  
   340  	if _, err = pq.EnqueueString(0, "value"); err != nil {
   341  		t.Error(err)
   342  	}
   343  
   344  	_, err = pq.PeekByOffset(0)
   345  	if err != nil {
   346  		t.Errorf("Expected to get nil error, got %s", err.Error())
   347  	}
   348  
   349  	if _, err = pq.Dequeue(); err != nil {
   350  		t.Error(err)
   351  	}
   352  
   353  	_, err = pq.PeekByOffset(0)
   354  	if err != ErrEmpty {
   355  		t.Errorf("Expected to get empty error, got %s", err.Error())
   356  	}
   357  }
   358  
   359  func TestPriorityQueuePeekByOffsetBoundsAsc(t *testing.T) {
   360  	file := fmt.Sprintf("test_db_%d", time.Now().UnixNano())
   361  	pq, err := OpenPriorityQueue(file, ASC)
   362  	if err != nil {
   363  		t.Error(err)
   364  	}
   365  	defer pq.Drop()
   366  
   367  	_, err = pq.PeekByOffset(0)
   368  	if err != ErrEmpty {
   369  		t.Errorf("Expected to get empty error, got %s", err.Error())
   370  	}
   371  
   372  	if _, err = pq.EnqueueString(0, "value"); err != nil {
   373  		t.Error(err)
   374  	}
   375  
   376  	_, err = pq.PeekByOffset(0)
   377  	if err != nil {
   378  		t.Errorf("Expected to get nil error, got %s", err.Error())
   379  	}
   380  
   381  	_, err = pq.PeekByOffset(1)
   382  	if err != ErrOutOfBounds {
   383  		t.Errorf("Expected to get queue out of bounds error, got %s", err.Error())
   384  	}
   385  
   386  	for p := 0; p <= 4; p++ {
   387  		for i := 1; i <= 10; i++ {
   388  			if _, err = pq.EnqueueString(uint8(p), fmt.Sprintf("value for item %d", i)); err != nil {
   389  				t.Error(err)
   390  			}
   391  		}
   392  	}
   393  
   394  	_, err = pq.PeekByOffset(50)
   395  	if err != nil {
   396  		t.Errorf("Expected to get nil error, got %s", err.Error())
   397  	}
   398  
   399  	_, err = pq.PeekByOffset(51)
   400  	if err != ErrOutOfBounds {
   401  		t.Errorf("Expected to get queue out of bounds error, got %s", err.Error())
   402  	}
   403  }
   404  
   405  func TestPriorityQueuePeekByOffsetBoundsDesc(t *testing.T) {
   406  	file := fmt.Sprintf("test_db_%d", time.Now().UnixNano())
   407  	pq, err := OpenPriorityQueue(file, DESC)
   408  	if err != nil {
   409  		t.Error(err)
   410  	}
   411  	defer pq.Drop()
   412  
   413  	_, err = pq.PeekByOffset(0)
   414  	if err != ErrEmpty {
   415  		t.Errorf("Expected to get empty error, got %s", err.Error())
   416  	}
   417  
   418  	if _, err = pq.EnqueueString(0, "value"); err != nil {
   419  		t.Error(err)
   420  	}
   421  
   422  	_, err = pq.PeekByOffset(0)
   423  	if err != nil {
   424  		t.Errorf("Expected to get nil error, got %s", err.Error())
   425  	}
   426  
   427  	_, err = pq.PeekByOffset(1)
   428  	if err != ErrOutOfBounds {
   429  		t.Errorf("Expected to get queue out of bounds error, got %s", err.Error())
   430  	}
   431  
   432  	for p := 0; p <= 4; p++ {
   433  		for i := 1; i <= 10; i++ {
   434  			if _, err = pq.EnqueueString(uint8(p), fmt.Sprintf("value for item %d", i)); err != nil {
   435  				t.Error(err)
   436  			}
   437  		}
   438  	}
   439  
   440  	_, err = pq.PeekByOffset(50)
   441  	if err != nil {
   442  		t.Errorf("Expected to get nil error, got %s", err.Error())
   443  	}
   444  
   445  	_, err = pq.PeekByOffset(51)
   446  	if err != ErrOutOfBounds {
   447  		t.Errorf("Expected to get queue out of bounds error, got %s", err.Error())
   448  	}
   449  }
   450  
   451  func TestPriorityQueuePeekByOffsetAsc(t *testing.T) {
   452  	file := fmt.Sprintf("test_db_%d", time.Now().UnixNano())
   453  	pq, err := OpenPriorityQueue(file, ASC)
   454  	if err != nil {
   455  		t.Error(err)
   456  	}
   457  	defer pq.Drop()
   458  
   459  	for p := 0; p <= 4; p++ {
   460  		for i := 1; i <= 10; i++ {
   461  			if _, err = pq.EnqueueString(uint8(p), fmt.Sprintf("value for item %d", i)); err != nil {
   462  				t.Error(err)
   463  			}
   464  		}
   465  	}
   466  
   467  	compStrFirst := "value for item 1"
   468  	compStrLast := "value for item 10"
   469  	compStr := "value for item 3"
   470  
   471  	peekFirstItem, err := pq.PeekByOffset(0)
   472  	if err != nil {
   473  		t.Error(err)
   474  	}
   475  
   476  	if peekFirstItem.Priority != 0 {
   477  		t.Errorf("Expected priority level to be 0, got %d", peekFirstItem.Priority)
   478  	}
   479  
   480  	if peekFirstItem.ToString() != compStrFirst {
   481  		t.Errorf("Expected string to be '%s', got '%s'", compStrFirst, peekFirstItem.ToString())
   482  	}
   483  
   484  	peekLastItem, err := pq.PeekByOffset(49)
   485  	if err != nil {
   486  		t.Error(err)
   487  	}
   488  
   489  	if peekLastItem.Priority != 4 {
   490  		t.Errorf("Expected priority level to be 4, got %d", peekLastItem.Priority)
   491  	}
   492  
   493  	if peekLastItem.ToString() != compStrLast {
   494  		t.Errorf("Expected string to be '%s', got '%s'", compStrLast, peekLastItem.ToString())
   495  	}
   496  
   497  	peekItem, err := pq.PeekByOffset(22)
   498  	if err != nil {
   499  		t.Error(err)
   500  	}
   501  
   502  	if peekItem.Priority != 2 {
   503  		t.Errorf("Expected priority level to be 2, got %d", peekItem.Priority)
   504  	}
   505  
   506  	if peekItem.ToString() != compStr {
   507  		t.Errorf("Expected string to be '%s', got '%s'", compStr, peekItem.ToString())
   508  	}
   509  
   510  	if pq.Length() != 50 {
   511  		t.Errorf("Expected queue length of 50, got %d", pq.Length())
   512  	}
   513  }
   514  
   515  func TestPriorityQueuePeekByOffsetDesc(t *testing.T) {
   516  	file := fmt.Sprintf("test_db_%d", time.Now().UnixNano())
   517  	pq, err := OpenPriorityQueue(file, DESC)
   518  	if err != nil {
   519  		t.Error(err)
   520  	}
   521  	defer pq.Drop()
   522  
   523  	for p := 0; p <= 4; p++ {
   524  		for i := 1; i <= 10; i++ {
   525  			if _, err = pq.EnqueueString(uint8(p), fmt.Sprintf("value for item %d", i)); err != nil {
   526  				t.Error(err)
   527  			}
   528  		}
   529  	}
   530  
   531  	compStrFirst := "value for item 1"
   532  	compStrLast := "value for item 10"
   533  	compStr := "value for item 3"
   534  
   535  	peekFirstItem, err := pq.PeekByOffset(0)
   536  	if err != nil {
   537  		t.Error(err)
   538  	}
   539  
   540  	if peekFirstItem.Priority != 4 {
   541  		t.Errorf("Expected priority level to be 4, got %d", peekFirstItem.Priority)
   542  	}
   543  
   544  	if peekFirstItem.ToString() != compStrFirst {
   545  		t.Errorf("Expected string to be '%s', got '%s'", compStrFirst, peekFirstItem.ToString())
   546  	}
   547  
   548  	peekLastItem, err := pq.PeekByOffset(49)
   549  	if err != nil {
   550  		t.Error(err)
   551  	}
   552  
   553  	if peekLastItem.Priority != 0 {
   554  		t.Errorf("Expected priority level to be 0, got %d", peekLastItem.Priority)
   555  	}
   556  
   557  	if peekLastItem.ToString() != compStrLast {
   558  		t.Errorf("Expected string to be '%s', got '%s'", compStrLast, peekLastItem.ToString())
   559  	}
   560  
   561  	peekItem, err := pq.PeekByOffset(32)
   562  	if err != nil {
   563  		t.Error(err)
   564  	}
   565  
   566  	if peekItem.Priority != 1 {
   567  		t.Errorf("Expected priority level to be 0, got %d", peekItem.Priority)
   568  	}
   569  
   570  	if peekItem.ToString() != compStr {
   571  		t.Errorf("Expected string to be '%s', got '%s'", compStr, peekItem.ToString())
   572  	}
   573  
   574  	if pq.Length() != 50 {
   575  		t.Errorf("Expected queue length of 50, got %d", pq.Length())
   576  	}
   577  }
   578  
   579  func TestPriorityQueuePeekByPriorityID(t *testing.T) {
   580  	file := fmt.Sprintf("test_db_%d", time.Now().UnixNano())
   581  	pq, err := OpenPriorityQueue(file, ASC)
   582  	if err != nil {
   583  		t.Error(err)
   584  	}
   585  	defer pq.Drop()
   586  
   587  	for p := 0; p <= 4; p++ {
   588  		for i := 1; i <= 10; i++ {
   589  			if _, err = pq.EnqueueString(uint8(p), fmt.Sprintf("value for item %d", i)); err != nil {
   590  				t.Error(err)
   591  			}
   592  		}
   593  	}
   594  
   595  	compStr := "value for item 3"
   596  
   597  	peekItem, err := pq.PeekByPriorityID(1, 3)
   598  	if err != nil {
   599  		t.Error(err)
   600  	}
   601  
   602  	if peekItem.Priority != 1 {
   603  		t.Errorf("Expected priority level to be 1, got %d", peekItem.Priority)
   604  	}
   605  
   606  	if peekItem.ToString() != compStr {
   607  		t.Errorf("Expected string to be '%s', got '%s'", compStr, peekItem.ToString())
   608  	}
   609  
   610  	if pq.Length() != 50 {
   611  		t.Errorf("Expected queue length of 50, got %d", pq.Length())
   612  	}
   613  }
   614  
   615  func TestPriorityQueueUpdate(t *testing.T) {
   616  	file := fmt.Sprintf("test_db_%d", time.Now().UnixNano())
   617  	pq, err := OpenPriorityQueue(file, ASC)
   618  	if err != nil {
   619  		t.Error(err)
   620  	}
   621  	defer pq.Drop()
   622  
   623  	for p := 0; p <= 4; p++ {
   624  		for i := 1; i <= 10; i++ {
   625  			if _, err = pq.EnqueueString(uint8(p), fmt.Sprintf("value for item %d", i)); err != nil {
   626  				t.Error(err)
   627  			}
   628  		}
   629  	}
   630  
   631  	item, err := pq.PeekByPriorityID(0, 3)
   632  	if err != nil {
   633  		t.Error(err)
   634  	}
   635  
   636  	oldCompStr := "value for item 3"
   637  	newCompStr := "new value for item 3"
   638  
   639  	if item.ToString() != oldCompStr {
   640  		t.Errorf("Expected string to be '%s', got '%s'", oldCompStr, item.ToString())
   641  	}
   642  
   643  	updatedItem, err := pq.Update(item.Priority, item.ID, []byte(newCompStr))
   644  	if err != nil {
   645  		t.Error(err)
   646  	}
   647  
   648  	if updatedItem.Priority != 0 {
   649  		t.Errorf("Expected priority level to be 0, got %d", item.Priority)
   650  	}
   651  
   652  	if updatedItem.ToString() != newCompStr {
   653  		t.Errorf("Expected current item value to be '%s', got '%s'", newCompStr, item.ToString())
   654  	}
   655  
   656  	newItem, err := pq.PeekByPriorityID(0, 3)
   657  	if err != nil {
   658  		t.Error(err)
   659  	}
   660  
   661  	if newItem.Priority != 0 {
   662  		t.Errorf("Expected priority level to be 0, got %d", newItem.Priority)
   663  	}
   664  
   665  	if newItem.ToString() != newCompStr {
   666  		t.Errorf("Expected new item value to be '%s', got '%s'", newCompStr, item.ToString())
   667  	}
   668  }
   669  
   670  func TestPriorityQueueUpdateString(t *testing.T) {
   671  	file := fmt.Sprintf("test_db_%d", time.Now().UnixNano())
   672  	pq, err := OpenPriorityQueue(file, ASC)
   673  	if err != nil {
   674  		t.Error(err)
   675  	}
   676  	defer pq.Drop()
   677  
   678  	for p := 0; p <= 4; p++ {
   679  		for i := 1; i <= 10; i++ {
   680  			if _, err = pq.EnqueueString(uint8(p), fmt.Sprintf("value for item %d", i)); err != nil {
   681  				t.Error(err)
   682  			}
   683  		}
   684  	}
   685  
   686  	item, err := pq.PeekByPriorityID(0, 3)
   687  	if err != nil {
   688  		t.Error(err)
   689  	}
   690  
   691  	oldCompStr := "value for item 3"
   692  	newCompStr := "new value for item 3"
   693  
   694  	if item.ToString() != oldCompStr {
   695  		t.Errorf("Expected string to be '%s', got '%s'", oldCompStr, item.ToString())
   696  	}
   697  
   698  	updatedItem, err := pq.UpdateString(item.Priority, item.ID, newCompStr)
   699  	if err != nil {
   700  		t.Error(err)
   701  	}
   702  
   703  	if updatedItem.Priority != 0 {
   704  		t.Errorf("Expected priority level to be 0, got %d", item.Priority)
   705  	}
   706  
   707  	if updatedItem.ToString() != newCompStr {
   708  		t.Errorf("Expected current item value to be '%s', got '%s'", newCompStr, item.ToString())
   709  	}
   710  
   711  	newItem, err := pq.PeekByPriorityID(0, 3)
   712  	if err != nil {
   713  		t.Error(err)
   714  	}
   715  
   716  	if newItem.Priority != 0 {
   717  		t.Errorf("Expected priority level to be 0, got %d", newItem.Priority)
   718  	}
   719  
   720  	if newItem.ToString() != newCompStr {
   721  		t.Errorf("Expected new item value to be '%s', got '%s'", newCompStr, item.ToString())
   722  	}
   723  }
   724  
   725  func TestPriorityQueueUpdateObject(t *testing.T) {
   726  	file := fmt.Sprintf("test_db_%d", time.Now().UnixNano())
   727  	pq, err := OpenPriorityQueue(file, ASC)
   728  	if err != nil {
   729  		t.Error(err)
   730  	}
   731  	defer pq.Drop()
   732  
   733  	type object struct {
   734  		Priority uint8
   735  		Value    int
   736  	}
   737  
   738  	for p := 0; p <= 4; p++ {
   739  		for i := 1; i <= 10; i++ {
   740  			if _, err = pq.EnqueueObject(uint8(p), object{uint8(p), i}); err != nil {
   741  				t.Error(err)
   742  			}
   743  		}
   744  	}
   745  
   746  	item, err := pq.PeekByPriorityID(0, 3)
   747  	if err != nil {
   748  		t.Error(err)
   749  	}
   750  
   751  	oldCompObj := object{0, 3}
   752  	newCompObj := object{0, 33}
   753  
   754  	var obj object
   755  	if err := item.ToObject(&obj); err != nil {
   756  		t.Error(err)
   757  	}
   758  
   759  	if obj != oldCompObj {
   760  		t.Errorf("Expected object to be '%+v', got '%+v'", oldCompObj, obj)
   761  	}
   762  
   763  	updatedItem, err := pq.UpdateObject(item.Priority, item.ID, newCompObj)
   764  	if err != nil {
   765  		t.Error(err)
   766  	}
   767  
   768  	if updatedItem.Priority != 0 {
   769  		t.Errorf("Expected priority level to be 0, got %d", item.Priority)
   770  	}
   771  
   772  	if err := updatedItem.ToObject(&obj); err != nil {
   773  		t.Error(err)
   774  	}
   775  
   776  	if obj != newCompObj {
   777  		t.Errorf("Expected current object to be '%+v', got '%+v'", newCompObj, obj)
   778  	}
   779  
   780  	newItem, err := pq.PeekByPriorityID(0, 3)
   781  	if err != nil {
   782  		t.Error(err)
   783  	}
   784  
   785  	if newItem.Priority != 0 {
   786  		t.Errorf("Expected priority level to be 0, got %d", newItem.Priority)
   787  	}
   788  
   789  	if err := newItem.ToObject(&obj); err != nil {
   790  		t.Error(err)
   791  	}
   792  
   793  	if obj != newCompObj {
   794  		t.Errorf("Expected new object to be '%+v', got '%+v'", newCompObj, obj)
   795  	}
   796  }
   797  
   798  func TestPriorityQueueUpdateObjectAsJSON(t *testing.T) {
   799  	file := fmt.Sprintf("test_db_%d", time.Now().UnixNano())
   800  	pq, err := OpenPriorityQueue(file, ASC)
   801  	if err != nil {
   802  		t.Error(err)
   803  	}
   804  	defer pq.Drop()
   805  
   806  	type subObject struct {
   807  		Value *int
   808  	}
   809  
   810  	type object struct {
   811  		Priority  uint8
   812  		Value     int
   813  		SubObject subObject
   814  	}
   815  
   816  	for p := 0; p <= 4; p++ {
   817  		for i := 1; i <= 10; i++ {
   818  			obj := object{
   819  				Priority: uint8(p),
   820  				Value:    i,
   821  				SubObject: subObject{
   822  					Value: &i,
   823  				},
   824  			}
   825  
   826  			if _, err = pq.EnqueueObjectAsJSON(uint8(p), obj); err != nil {
   827  				t.Error(err)
   828  			}
   829  		}
   830  	}
   831  
   832  	item, err := pq.PeekByPriorityID(0, 3)
   833  	if err != nil {
   834  		t.Error(err)
   835  	}
   836  
   837  	oldCompObjVal := 3
   838  	oldCompObj := object{
   839  		Priority: 0,
   840  		Value:    3,
   841  		SubObject: subObject{
   842  			Value: &oldCompObjVal,
   843  		},
   844  	}
   845  	newCompObjVal := 33
   846  	newCompObj := object{
   847  		Priority: 0,
   848  		Value:    33,
   849  		SubObject: subObject{
   850  			Value: &newCompObjVal,
   851  		},
   852  	}
   853  
   854  	var obj object
   855  	if err := item.ToObjectFromJSON(&obj); err != nil {
   856  		t.Error(err)
   857  	}
   858  
   859  	if *obj.SubObject.Value != *oldCompObj.SubObject.Value {
   860  		t.Errorf("Expected object subobject value to be '%+v', got '%+v'", *oldCompObj.SubObject.Value, *obj.SubObject.Value)
   861  	}
   862  
   863  	updatedItem, err := pq.UpdateObjectAsJSON(item.Priority, item.ID, newCompObj)
   864  	if err != nil {
   865  		t.Error(err)
   866  	}
   867  
   868  	if updatedItem.Priority != 0 {
   869  		t.Errorf("Expected priority level to be 0, got %d", item.Priority)
   870  	}
   871  
   872  	if err := updatedItem.ToObjectFromJSON(&obj); err != nil {
   873  		t.Error(err)
   874  	}
   875  
   876  	if *obj.SubObject.Value != *newCompObj.SubObject.Value {
   877  		t.Errorf("Expected current object subobject value to be '%+v', got '%+v'", *newCompObj.SubObject.Value, *obj.SubObject.Value)
   878  	}
   879  
   880  	newItem, err := pq.PeekByPriorityID(0, 3)
   881  	if err != nil {
   882  		t.Error(err)
   883  	}
   884  
   885  	if newItem.Priority != 0 {
   886  		t.Errorf("Expected priority level to be 0, got %d", newItem.Priority)
   887  	}
   888  
   889  	if err := newItem.ToObjectFromJSON(&obj); err != nil {
   890  		t.Error(err)
   891  	}
   892  
   893  	if *obj.SubObject.Value != *newCompObj.SubObject.Value {
   894  		t.Errorf("Expected current object subobject value to be '%+v', got '%+v'", *newCompObj.SubObject.Value, *obj.SubObject.Value)
   895  	}
   896  }
   897  
   898  func TestPriorityQueueUpdateOutOfBounds(t *testing.T) {
   899  	file := fmt.Sprintf("test_db_%d", time.Now().UnixNano())
   900  	pq, err := OpenPriorityQueue(file, ASC)
   901  	if err != nil {
   902  		t.Error(err)
   903  	}
   904  	defer pq.Drop()
   905  
   906  	for p := 0; p <= 4; p++ {
   907  		for i := 1; i <= 10; i++ {
   908  			if _, err = pq.EnqueueString(uint8(p), fmt.Sprintf("value for item %d", i)); err != nil {
   909  				t.Error(err)
   910  			}
   911  		}
   912  	}
   913  
   914  	if pq.Length() != 50 {
   915  		t.Errorf("Expected queue length of 50, got %d", pq.Length())
   916  	}
   917  
   918  	deqItem, err := pq.DequeueByPriority(3)
   919  	if err != nil {
   920  		t.Error(err)
   921  	}
   922  
   923  	if pq.Length() != 49 {
   924  		t.Errorf("Expected queue length of 49, got %d", pq.Length())
   925  	}
   926  
   927  	if _, err = pq.Update(deqItem.Priority, deqItem.ID, []byte(`new value`)); err != ErrOutOfBounds {
   928  		t.Errorf("Expected to get queue out of bounds error, got %s", err.Error())
   929  	}
   930  
   931  	if _, err = pq.Update(deqItem.Priority, deqItem.ID+1, []byte(`new value`)); err != nil {
   932  		t.Error(err)
   933  	}
   934  }
   935  
   936  func TestPriorityQueueHigherPriorityAsc(t *testing.T) {
   937  	file := fmt.Sprintf("test_db_%d", time.Now().UnixNano())
   938  	pq, err := OpenPriorityQueue(file, ASC)
   939  	if err != nil {
   940  		t.Error(err)
   941  	}
   942  	defer pq.Drop()
   943  
   944  	for p := 5; p <= 9; p++ {
   945  		for i := 1; i <= 10; i++ {
   946  			if _, err = pq.EnqueueString(uint8(p), fmt.Sprintf("value for item %d", i)); err != nil {
   947  				t.Error(err)
   948  			}
   949  		}
   950  	}
   951  
   952  	item, err := pq.Dequeue()
   953  	if err != nil {
   954  		t.Error(err)
   955  	}
   956  
   957  	if item.Priority != 5 {
   958  		t.Errorf("Expected priority level to be 5, got %d", item.Priority)
   959  	}
   960  
   961  	_, err = pq.EnqueueString(2, "value")
   962  	if err != nil {
   963  		t.Error(err)
   964  	}
   965  
   966  	higherItem, err := pq.Dequeue()
   967  	if err != nil {
   968  		t.Error(err)
   969  	}
   970  
   971  	if higherItem.Priority != 2 {
   972  		t.Errorf("Expected priority level to be 2, got %d", higherItem.Priority)
   973  	}
   974  }
   975  
   976  func TestPriorityQueueHigherPriorityDesc(t *testing.T) {
   977  	file := fmt.Sprintf("test_db_%d", time.Now().UnixNano())
   978  	pq, err := OpenPriorityQueue(file, DESC)
   979  	if err != nil {
   980  		t.Error(err)
   981  	}
   982  	defer pq.Drop()
   983  
   984  	for p := 5; p <= 9; p++ {
   985  		for i := 1; i <= 10; i++ {
   986  			if _, err = pq.EnqueueString(uint8(p), fmt.Sprintf("value for item %d", i)); err != nil {
   987  				t.Error(err)
   988  			}
   989  		}
   990  	}
   991  
   992  	item, err := pq.Dequeue()
   993  	if err != nil {
   994  		t.Error(err)
   995  	}
   996  
   997  	if item.Priority != 9 {
   998  		t.Errorf("Expected priority level to be 9, got %d", item.Priority)
   999  	}
  1000  
  1001  	_, err = pq.EnqueueString(12, "value")
  1002  	if err != nil {
  1003  		t.Error(err)
  1004  	}
  1005  
  1006  	higherItem, err := pq.Dequeue()
  1007  	if err != nil {
  1008  		t.Error(err)
  1009  	}
  1010  
  1011  	if higherItem.Priority != 12 {
  1012  		t.Errorf("Expected priority level to be 12, got %d", higherItem.Priority)
  1013  	}
  1014  }
  1015  
  1016  func TestPriorityQueueEmpty(t *testing.T) {
  1017  	file := fmt.Sprintf("test_db_%d", time.Now().UnixNano())
  1018  	pq, err := OpenPriorityQueue(file, ASC)
  1019  	if err != nil {
  1020  		t.Error(err)
  1021  	}
  1022  	defer pq.Drop()
  1023  
  1024  	_, err = pq.EnqueueString(0, "value for item")
  1025  	if err != nil {
  1026  		t.Error(err)
  1027  	}
  1028  
  1029  	_, err = pq.Dequeue()
  1030  	if err != nil {
  1031  		t.Error(err)
  1032  	}
  1033  
  1034  	_, err = pq.Dequeue()
  1035  	if err != ErrEmpty {
  1036  		t.Errorf("Expected to get empty error, got %s", err.Error())
  1037  	}
  1038  }
  1039  
  1040  func TestPriorityQueueOutOfBounds(t *testing.T) {
  1041  	file := fmt.Sprintf("test_db_%d", time.Now().UnixNano())
  1042  	pq, err := OpenPriorityQueue(file, ASC)
  1043  	if err != nil {
  1044  		t.Error(err)
  1045  	}
  1046  	defer pq.Drop()
  1047  
  1048  	_, err = pq.EnqueueString(0, "value for item")
  1049  	if err != nil {
  1050  		t.Error(err)
  1051  	}
  1052  
  1053  	_, err = pq.PeekByOffset(2)
  1054  	if err != ErrOutOfBounds {
  1055  		t.Errorf("Expected to get queue out of bounds error, got %s", err.Error())
  1056  	}
  1057  }
  1058  
  1059  func BenchmarkPriorityQueueEnqueue(b *testing.B) {
  1060  	// Open test database
  1061  	file := fmt.Sprintf("test_db_%d", time.Now().UnixNano())
  1062  	pq, err := OpenPriorityQueue(file, ASC)
  1063  	if err != nil {
  1064  		b.Error(err)
  1065  	}
  1066  	defer pq.Drop()
  1067  
  1068  	b.ResetTimer()
  1069  	b.ReportAllocs()
  1070  
  1071  	for n := 0; n < b.N; n++ {
  1072  		_, _ = pq.EnqueueString(0, "value")
  1073  	}
  1074  }
  1075  
  1076  func BenchmarkPriorityQueueDequeue(b *testing.B) {
  1077  	// Open test database
  1078  	file := fmt.Sprintf("test_db_%d", time.Now().UnixNano())
  1079  	pq, err := OpenPriorityQueue(file, ASC)
  1080  	if err != nil {
  1081  		b.Error(err)
  1082  	}
  1083  	defer pq.Drop()
  1084  
  1085  	// Fill with dummy data
  1086  	for n := 0; n < b.N; n++ {
  1087  		if _, err = pq.EnqueueString(uint8(math.Mod(float64(n), 255)), "value"); err != nil {
  1088  			b.Error(err)
  1089  		}
  1090  	}
  1091  
  1092  	// Start benchmark
  1093  	b.ResetTimer()
  1094  	b.ReportAllocs()
  1095  
  1096  	for n := 0; n < b.N; n++ {
  1097  		_, _ = pq.Dequeue()
  1098  	}
  1099  }