//
//  OmPriorityQueueTests.cpp
//  OmUtil
//
//  Created by David Van Brink on 5/31/17.
//  Copyright (c) 2017 omino.com. All rights reserved.
//

#include "OmPriorityQueueTests.h"
#include "OmAsserts.h"
#include "Om.h"

OMTEST(pqTest1)
{
    OmPriorityQueue q;
    
    uint32_t id1 = q.insert(1, (void *)100);
    uint32_t id2 = q.insert(2, (void *)200);
    uint32_t id3 = q.insert(3, (void *)300);
    
    ASSERT_EQUALS_INT("size", 3, q.size());
    
    q.remove(id1);
    ASSERT_EQUALS_INT("size", 2, q.size());
    q.remove(id3);
    ASSERT_EQUALS_INT("size", 1, q.size());
    q.remove(id2);
    ASSERT_EQUALS_INT("size", 0, q.size());
}

OMTEST(pqTestBunch)
{
    OmPriorityQueue q;
    
    int k = 200;
    int st = 17;
    int ixW = 0;
    for(int ix = 0; ix < k; ix++)
    {
        ixW = (ixW + st) % k;
        q.insert(ixW, (void *)(long)(ixW * 100));
    }
    
    ASSERT_EQUALS_INT("size", k, q.size());
    
    for(int ix = 0; ix < k; ix++)
    {
        ASSERT_EQUALS_INT("top now", ix, q.topT());
        q.pop();
        ASSERT_EQUALS_INT("size now", 199 - ix, q.size());
    }
}

OMTEST(pqTestRemovals)
{
    OmPriorityQueue q;

    int k = 2000;
    int st = 2017; // this combination proves need for percolate UP as well as down in removals.
    int ixW = 0;
    
    std::vector<int> ids(k);

    for(int ix = 0; ix < k; ix++)
    {
        ixW = (ixW + st) % k;
        ids[ixW] = q.insert(ixW, (void *)(long)(ixW * 100));
    }
    
    // remove all multiples of eleven mod 3.
    for(int ix = 3; ix < k; ix += 11)
    {
        q.remove(ids[ix]);
    }
    
    for(int ix = 0; ix < k; ix++)
    {
        if(ix % 11 == 3)
            continue; // we removed those ones.
        ASSERT_EQUALS_INT("top now", ix, q.topT());
        q.pop();
    }
}

OMTEST(pqTestClear)
{
    OmPriorityQueue q;
    
    int k = 2000;
    int st = 2017; // this combination proves need for percolate UP as well as down in removals.
    int ixW = 0;
    
    std::vector<int> ids(k);
    
    for(int ix = 0; ix < k; ix++)
    {
        ixW = (ixW + st) % k;
        ids[ixW] = q.insert(ixW, (void *)(long)(ixW * 100));
    }
    
    q.clear();
    
    ASSERT_EQUALS_INT("empty?", 0, q.size());
}


void allPriorityQueueTests()
{
    pqTest1();
    pqTestBunch();
    pqTestRemovals();
    pqTestClear();
}
