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 }