// File: jansucan[P]diff-dd/src/create.cpp
// Function: DiffFinder::findDiffInPages(Page, Page, unsigned long)
Diff findDiffInPages(Page old_page, Page new_page,
                         uint64_t offset_in_stream)
    {
        const char *old_data{old_page.getData().get()};
        const char *new_data{new_page.getData().get()};
        const uint64_t data_size_bytes{old_page.getSize()};

        assert(offset_in_stream >= new_page.getStart());
        size_t offset_in_pages{offset_in_stream - new_page.getStart()};

        // Find offset of the first different byte
        for (; offset_in_pages < data_size_bytes; ++offset_in_pages) {
            if (new_data[offset_in_pages] != old_data[offset_in_pages]) {
                break;
            }
        }
        const size_t start_in_pages{offset_in_pages};

        if (offset_in_pages < data_size_bytes) {
            // Different byte found. Start searching for a same byte immediately
            // after.
            ++offset_in_pages;
        }

        // Find offset of the first same byte
        for (; offset_in_pages < data_size_bytes; ++offset_in_pages) {
            if (new_data[offset_in_pages] == old_data[offset_in_pages]) {
                break;
            }
        }
        const size_t end_in_pages{offset_in_pages};

        // In the case when no different byte is found, the end offset will be
        // the same as the start offset

        const uint64_t start_in_stream{new_page.getStart() + start_in_pages};
        const uint64_t end_in_stream{new_page.getStart() + end_in_pages};
        if (start_in_stream == end_in_stream) {
            return Diff{start_in_stream};
        } else {
            return Diff{new_page, start_in_stream, end_in_stream};
        }
    }

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x100, %rsp            # imm = 0x100
movq %rcx, -0xc8(%rbp)
movq %rdx, -0xd0(%rbp)
movq %rsi, %rax
movq -0xd0(%rbp), %rsi
movq %rdi, -0xf0(%rbp)
movq %rdi, %rdx
movq %rdx, -0xe8(%rbp)
movq %rdi, -0x8(%rbp)
movq %rax, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
movq %rcx, -0x20(%rbp)
movq %r8, -0x28(%rbp)
leaq -0x40(%rbp), %rdi
callq 0x76e0
leaq -0x40(%rbp), %rdi
callq 0x4970
movq %rax, -0xe0(%rbp)
leaq -0x40(%rbp), %rdi
callq 0x47d0
movq -0xe0(%rbp), %rax
movq -0xc8(%rbp), %rsi
movq %rax, -0x30(%rbp)
leaq -0x58(%rbp), %rdi
callq 0x76e0
leaq -0x58(%rbp), %rdi
callq 0x4970
movq %rax, -0xd8(%rbp)
leaq -0x58(%rbp), %rdi
callq 0x47d0
movq -0xd8(%rbp), %rax
movq -0xd0(%rbp), %rdi
movq %rax, -0x48(%rbp)
callq 0x8f20
movq -0xc8(%rbp), %rdi
movq %rax, -0x60(%rbp)
movq -0x28(%rbp), %rax
movq %rax, -0xc0(%rbp)
callq 0x7710
movq %rax, %rcx
movq -0xc0(%rbp), %rax
cmpq %rcx, %rax
jb 0x9131
jmp 0x9150
leaq 0x5438(%rip), %rdi      # 0xe570
leaq 0x5212(%rip), %rsi      # 0xe351
movl $0x13a, %edx            # imm = 0x13A
leaq 0x544d(%rip), %rcx      # 0xe598
callq 0x31c0
movq -0xc8(%rbp), %rdi
movq -0x28(%rbp), %rax
movq %rax, -0xf8(%rbp)
callq 0x7710
movq %rax, %rcx
movq -0xf8(%rbp), %rax
subq %rcx, %rax
movq %rax, -0x68(%rbp)
movq -0x68(%rbp), %rax
cmpq -0x60(%rbp), %rax
jae 0x91b0
movq -0x48(%rbp), %rax
movq -0x68(%rbp), %rcx
movsbl (%rax,%rcx), %eax
movq -0x30(%rbp), %rcx
movq -0x68(%rbp), %rdx
movsbl (%rcx,%rdx), %ecx
cmpl %ecx, %eax
je 0x91a0
jmp 0x91b0
jmp 0x91a2
movq -0x68(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x68(%rbp)
jmp 0x9178
movq -0x68(%rbp), %rax
movq %rax, -0x70(%rbp)
movq -0x68(%rbp), %rax
cmpq -0x60(%rbp), %rax
jae 0x91ce
movq -0x68(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x68(%rbp)
jmp 0x91d0
movq -0x68(%rbp), %rax
cmpq -0x60(%rbp), %rax
jae 0x9208
movq -0x48(%rbp), %rax
movq -0x68(%rbp), %rcx
movsbl (%rax,%rcx), %eax
movq -0x30(%rbp), %rcx
movq -0x68(%rbp), %rdx
movsbl (%rcx,%rdx), %ecx
cmpl %ecx, %eax
jne 0x91f8
jmp 0x9208
jmp 0x91fa
movq -0x68(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x68(%rbp)
jmp 0x91d0
movq -0xc8(%rbp), %rdi
movq -0x68(%rbp), %rax
movq %rax, -0x78(%rbp)
callq 0x7710
movq -0xc8(%rbp), %rdi
addq -0x70(%rbp), %rax
movq %rax, -0x80(%rbp)
callq 0x7710
addq -0x78(%rbp), %rax
movq %rax, -0x88(%rbp)
movq -0x80(%rbp), %rax
cmpq -0x88(%rbp), %rax
jne 0x925a
movq -0xf0(%rbp), %rdi
movq -0x80(%rbp), %rsi
callq 0x8c80
jmp 0x92c2
movq -0xc8(%rbp), %rsi
leaq -0xa8(%rbp), %rdi
movq %rdi, -0x100(%rbp)
callq 0x92e0
movq -0xf0(%rbp), %rdi
movq -0x100(%rbp), %rsi
movq -0x80(%rbp), %rdx
movq -0x88(%rbp), %rcx
callq 0x94e0
jmp 0x9294
leaq -0xa8(%rbp), %rdi
callq 0x8d80
jmp 0x92c2
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xb0(%rbp)
movl %eax, -0xb4(%rbp)
leaq -0xa8(%rbp), %rdi
callq 0x8d80
jmp 0x92d2
movq -0xe8(%rbp), %rax
addq $0x100, %rsp            # imm = 0x100
popq %rbp
retq
movq -0xb0(%rbp), %rdi
callq 0x3490
nop