// File: dlbeer[P]summary_map/test_rbt.cpp
// Function: main
int main(int argc, char **argv)
{
    const char *path = "/usr/share/dict/words";

    if (argc > 1)
	path = argv[1];

    std::cout << "Loading words from " << path << '\n';

    test_vector vec;
    test_map m;

    load_words(path, vec, 1000);
    assert(vec.size() == 1000);
    check_absent(m, vec, 0, vec.size());

    std::cout << "Inserting...\n";
    shuffle(vec, 1);

    for (unsigned int i = 0; i < vec.size(); i++) {
	m.insert(vec[i]);
	assert(m.size() == i + 1);
	m.check();
    }

    check_present(m, vec, 0, vec.size());

    std::cout << "Removing some...\n";
    shuffle(vec, 2);

    for (int i = vec.size() - 1; i >= (signed)vec.size() / 2; i--) {
	m.erase(vec[i].first);
	assert(m.size() == (unsigned)i);
	m.check();
    }

    check_present(m, vec, 0, vec.size() / 2);
    check_absent(m, vec, vec.size() / 2, vec.size());

    std::cout << "Adding some...\n";

    for (unsigned int i = vec.size() / 2; i < vec.size(); i++) {
	m.insert(vec[i]);
	assert(m.size() == i + 1);
	m.check();
    }

    check_present(m, vec, 0, vec.size());

    std::cout << "Removing...\n";
    shuffle(vec, 3);

    for (int i = vec.size() - 1; i >= 0; i--) {
	m.erase(vec[i].first);
	assert(m.size() == (unsigned)i);
	m.check();
    }

    check_absent(m, vec, 0, vec.size());

    return 0;
}

// Assembly:
subq $0x1a8, %rsp            # imm = 0x1A8
movl $0x0, 0x1a4(%rsp)
movl %edi, 0x1a0(%rsp)
movq %rsi, 0x198(%rsp)
leaq 0x3c6c(%rip), %rax      # 0x6004
movq %rax, 0x190(%rsp)
cmpl $0x1, 0x1a0(%rsp)
jle 0x23be
movq 0x198(%rsp), %rax
movq 0x8(%rax), %rax
movq %rax, 0x190(%rsp)
movq 0x6c13(%rip), %rdi      # 0x8fd8
leaq 0x3c4e(%rip), %rsi      # 0x601a
callq 0x2140
movq %rax, %rdi
movq 0x190(%rsp), %rsi
callq 0x2140
movq %rax, %rdi
movl $0xa, %esi
callq 0x2170
leaq 0x178(%rsp), %rdi
callq 0x2cd0
leaq 0x120(%rsp), %rdi
callq 0x2ce0
jmp 0x240a
movq 0x190(%rsp), %rdi
leaq 0x178(%rsp), %rsi
movl $0x3e8, %edx            # imm = 0x3E8
callq 0x4be0
jmp 0x2426
leaq 0x178(%rsp), %rdi
callq 0x2d50
cmpq $0x3e8, %rax            # imm = 0x3E8
jne 0x243d
jmp 0x248e
leaq 0x3bea(%rip), %rdi      # 0x602e
leaq 0x3bf6(%rip), %rsi      # 0x6041
movl $0x3c, %edx
leaq 0x3bf7(%rip), %rcx      # 0x604e
callq 0x20e0
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x118(%rsp)
movl %eax, 0x114(%rsp)
jmp 0x2a8f
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x118(%rsp)
movl %eax, 0x114(%rsp)
jmp 0x2a82
leaq 0x178(%rsp), %rdi
movq %rdi, 0x88(%rsp)
callq 0x2d50
movq 0x88(%rsp), %rsi
movl %eax, %ecx
leaq 0x120(%rsp), %rdi
xorl %edx, %edx
callq 0x2ab0
jmp 0x24be
movq 0x6b13(%rip), %rdi      # 0x8fd8
leaq 0x3b99(%rip), %rsi      # 0x6065
callq 0x2140
jmp 0x24d3
leaq 0x178(%rsp), %rdi
movl $0x1, %esi
callq 0x4e10
jmp 0x24e7
movl $0x0, 0x110(%rsp)
movl 0x110(%rsp), %eax
movq %rax, 0x80(%rsp)
leaq 0x178(%rsp), %rdi
callq 0x2d50
movq %rax, %rcx
movq 0x80(%rsp), %rax
cmpq %rcx, %rax
jae 0x2627
movl 0x110(%rsp), %eax
movl %eax, %esi
leaq 0x178(%rsp), %rdi
callq 0x2e20
movq %rax, %rsi
leaq 0xe8(%rsp), %rdi
callq 0x2e40
jmp 0x254a
leaq 0x120(%rsp), %rdi
leaq 0xe8(%rsp), %rsi
callq 0x2d70
movb %dl, 0x77(%rsp)
movq %rax, 0x78(%rsp)
jmp 0x256a
movb 0x77(%rsp), %al
movq 0x78(%rsp), %rcx
movq %rcx, 0xd8(%rsp)
movb %al, 0xe0(%rsp)
leaq 0xe8(%rsp), %rdi
callq 0x2e80
leaq 0x120(%rsp), %rdi
callq 0x2e90
movq %rax, 0x68(%rsp)
jmp 0x25a3
movq 0x68(%rsp), %rax
movl 0x110(%rsp), %ecx
addl $0x1, %ecx
movl %ecx, %ecx
cmpq %rcx, %rax
jne 0x25bb
jmp 0x2600
leaq 0x3ab1(%rip), %rdi      # 0x6073
leaq 0x3a78(%rip), %rsi      # 0x6041
movl $0x44, %edx
leaq 0x3a79(%rip), %rcx      # 0x604e
callq 0x20e0
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x118(%rsp)
movl %eax, 0x114(%rsp)
leaq 0xe8(%rsp), %rdi
callq 0x2e80
jmp 0x2a82
leaq 0x120(%rsp), %rdi
callq 0x2ea0
jmp 0x260f
jmp 0x2611
movl 0x110(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x110(%rsp)
jmp 0x24f2
leaq 0x178(%rsp), %rdi
movq %rdi, 0x60(%rsp)
callq 0x2d50
movq 0x60(%rsp), %rsi
movl %eax, %ecx
leaq 0x120(%rsp), %rdi
xorl %edx, %edx
callq 0x2b70
jmp 0x2651
movq 0x6980(%rip), %rdi      # 0x8fd8
leaq 0x3a26(%rip), %rsi      # 0x6085
callq 0x2140
jmp 0x2666
leaq 0x178(%rsp), %rdi
movl $0x2, %esi
callq 0x4e10
jmp 0x267a
leaq 0x178(%rsp), %rdi
callq 0x2d50
subq $0x1, %rax
movl %eax, 0xd4(%rsp)
movl 0xd4(%rsp), %eax
movl %eax, 0x5c(%rsp)
leaq 0x178(%rsp), %rdi
callq 0x2d50
movl $0x2, %ecx
cltd
idivl %ecx
movl %eax, %ecx
movl 0x5c(%rsp), %eax
cmpl %ecx, %eax
jl 0x2754
movslq 0xd4(%rsp), %rsi
leaq 0x178(%rsp), %rdi
callq 0x2e20
movq %rax, %rsi
leaq 0x120(%rsp), %rdi
callq 0x2f40
jmp 0x26e7
leaq 0x120(%rsp), %rdi
callq 0x2e90
movq %rax, 0x50(%rsp)
jmp 0x26fb
movq 0x50(%rsp), %rax
movl 0xd4(%rsp), %ecx
cmpq %rcx, %rax
jne 0x270e
jmp 0x272d
leaq 0x3982(%rip), %rdi      # 0x6097
leaq 0x3925(%rip), %rsi      # 0x6041
movl $0x4f, %edx
leaq 0x3926(%rip), %rcx      # 0x604e
callq 0x20e0
leaq 0x120(%rsp), %rdi
callq 0x2ea0
jmp 0x273c
jmp 0x273e
movl 0xd4(%rsp), %eax
addl $-0x1, %eax
movl %eax, 0xd4(%rsp)
jmp 0x2692
leaq 0x178(%rsp), %rdi
movq %rdi, 0x48(%rsp)
callq 0x2d50
movq 0x48(%rsp), %rsi
shrq %rax
movl %eax, %ecx
leaq 0x120(%rsp), %rdi
xorl %edx, %edx
callq 0x2b70
jmp 0x2781
leaq 0x178(%rsp), %rdi
movq %rdi, 0x38(%rsp)
callq 0x2d50
movq 0x38(%rsp), %rdi
shrq %rax
movl %eax, 0x44(%rsp)
callq 0x2d50
movq 0x38(%rsp), %rsi
movl 0x44(%rsp), %edx
movl %eax, %ecx
leaq 0x120(%rsp), %rdi
callq 0x2ab0
jmp 0x27be
movq 0x6813(%rip), %rdi      # 0x8fd8
leaq 0x38e3(%rip), %rsi      # 0x60af
callq 0x2140
jmp 0x27d3
leaq 0x178(%rsp), %rdi
callq 0x2d50
shrq %rax
movl %eax, 0xd0(%rsp)
movl 0xd0(%rsp), %eax
movq %rax, 0x30(%rsp)
leaq 0x178(%rsp), %rdi
callq 0x2d50
movq %rax, %rcx
movq 0x30(%rsp), %rax
cmpq %rcx, %rax
jae 0x2919
movl 0xd0(%rsp), %eax
movl %eax, %esi
leaq 0x178(%rsp), %rdi
callq 0x2e20
movq %rax, %rsi
leaq 0xa8(%rsp), %rdi
callq 0x2e40
jmp 0x283c
leaq 0x120(%rsp), %rdi
leaq 0xa8(%rsp), %rsi
callq 0x2d70
movb %dl, 0x27(%rsp)
movq %rax, 0x28(%rsp)
jmp 0x285c
movb 0x27(%rsp), %al
movq 0x28(%rsp), %rcx
movq %rcx, 0x98(%rsp)
movb %al, 0xa0(%rsp)
leaq 0xa8(%rsp), %rdi
callq 0x2e80
leaq 0x120(%rsp), %rdi
callq 0x2e90
movq %rax, 0x18(%rsp)
jmp 0x2895
movq 0x18(%rsp), %rax
movl 0xd0(%rsp), %ecx
addl $0x1, %ecx
movl %ecx, %ecx
cmpq %rcx, %rax
jne 0x28ad
jmp 0x28f2
leaq 0x37bf(%rip), %rdi      # 0x6073
leaq 0x3786(%rip), %rsi      # 0x6041
movl $0x5a, %edx
leaq 0x3787(%rip), %rcx      # 0x604e
callq 0x20e0
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x118(%rsp)
movl %eax, 0x114(%rsp)
leaq 0xa8(%rsp), %rdi
callq 0x2e80
jmp 0x2a82
leaq 0x120(%rsp), %rdi
callq 0x2ea0
jmp 0x2901
jmp 0x2903
movl 0xd0(%rsp), %eax
addl $0x1, %eax
movl %eax, 0xd0(%rsp)
jmp 0x27ea
leaq 0x178(%rsp), %rdi
movq %rdi, 0x10(%rsp)
callq 0x2d50
movq 0x10(%rsp), %rsi
movl %eax, %ecx
leaq 0x120(%rsp), %rdi
xorl %edx, %edx
callq 0x2b70
jmp 0x2943
movq 0x668e(%rip), %rdi      # 0x8fd8
leaq 0x376e(%rip), %rsi      # 0x60bf
callq 0x2140
jmp 0x2958
leaq 0x178(%rsp), %rdi
movl $0x3, %esi
callq 0x4e10
jmp 0x296c
leaq 0x178(%rsp), %rdi
callq 0x2d50
subq $0x1, %rax
movl %eax, 0x94(%rsp)
cmpl $0x0, 0x94(%rsp)
jl 0x2a26
movslq 0x94(%rsp), %rsi
leaq 0x178(%rsp), %rdi
callq 0x2e20
movq %rax, %rsi
leaq 0x120(%rsp), %rdi
callq 0x2f40
jmp 0x29b9
leaq 0x120(%rsp), %rdi
callq 0x2e90
movq %rax, 0x8(%rsp)
jmp 0x29cd
movq 0x8(%rsp), %rax
movl 0x94(%rsp), %ecx
cmpq %rcx, %rax
jne 0x29e0
jmp 0x29ff
leaq 0x36b0(%rip), %rdi      # 0x6097
leaq 0x3653(%rip), %rsi      # 0x6041
movl $0x65, %edx
leaq 0x3654(%rip), %rcx      # 0x604e
callq 0x20e0
leaq 0x120(%rsp), %rdi
callq 0x2ea0
jmp 0x2a0e
jmp 0x2a10
movl 0x94(%rsp), %eax
addl $-0x1, %eax
movl %eax, 0x94(%rsp)
jmp 0x2984
leaq 0x178(%rsp), %rdi
movq %rdi, (%rsp)
callq 0x2d50
movq (%rsp), %rsi
movl %eax, %ecx
leaq 0x120(%rsp), %rdi
xorl %edx, %edx
callq 0x2ab0
jmp 0x2a4e
movl $0x0, 0x1a4(%rsp)
leaq 0x120(%rsp), %rdi
callq 0x2fc0
leaq 0x178(%rsp), %rdi
callq 0x3010
movl 0x1a4(%rsp), %eax
addq $0x1a8, %rsp            # imm = 0x1A8
retq
leaq 0x120(%rsp), %rdi
callq 0x2fc0
leaq 0x178(%rsp), %rdi
callq 0x3010
movq 0x118(%rsp), %rdi
callq 0x21f0
nopl (%rax)