// File: cybozu[P]yrmcds/src/memcache/replication.cpp
// Function: yrmcds::memcache::repl_recv(char const*, unsigned long, cybozu::hash_map<yrmcds::memcache::object>&)
std::size_t repl_recv(const char* p, std::size_t len,
                      cybozu::hash_map<object>& hash) {
    std::size_t consumed = 0;
    while( len > 0 ) {
        if( ! is_binary_request(p) )
            throw std::runtime_error("Invalid replication data");

        binary_request parser(p, len);
        std::size_t n = parser.length();
        if( n == 0 ) break;
        p += n;
        len -= n;
        consumed += n;

        const char* key_data;
        std::size_t key_len;
        cybozu::hash_map<object>::handler h = nullptr;
        cybozu::hash_map<object>::creator c = nullptr;

        switch( parser.command() ) {
        case binary_command::SetQ:
            h = [&parser](const cybozu::hash_key&, object& obj) -> bool {
                const char* p2;
                std::size_t len2;
                std::tie(p2, len2) = parser.data();
                ++ g_stats.repl_updated;
                obj.set(p2, len2, parser.flags(), parser.exptime());
                return true;
            };
            c = [&parser](const cybozu::hash_key&) -> object {
                const char* p2;
                std::size_t len2;
                std::tie(p2, len2) = parser.data();
                ++ g_stats.repl_created;
                return object(p2, len2, parser.flags(), parser.exptime());
            };
            std::tie(key_data, key_len) = parser.key();
            cybozu::logger::debug() << "repl: set "
                                    << std::string(key_data, key_len);
            hash.apply_nolock(cybozu::hash_key(key_data, key_len), h, c);
            break;
        case binary_command::Touch:
            h = [&parser](const cybozu::hash_key&, object& obj) -> bool {
                ++ g_stats.repl_updated;
                obj.touch( parser.exptime() );
                return true;
            };
            std::tie(key_data, key_len) = parser.key();
            cybozu::logger::debug() << "repl: touch "
                                    << std::string(key_data, key_len);
            hash.apply_nolock(cybozu::hash_key(key_data, key_len), h, c);
            break;
        case binary_command::DeleteQ:
            std::tie(key_data, key_len) = parser.key();
            cybozu::logger::debug() << "repl: remove "
                                    << std::string(key_data, key_len);
            ++ g_stats.repl_removed;
            hash.remove_nolock(cybozu::hash_key(key_data, key_len), nullptr);
            break;
        default:
            cybozu::logger::error() << "Unknown replication command"
                                    << std::hex
                                    << (unsigned int)parser.command();
        }
    }
    return consumed;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x3e0, %rsp            # imm = 0x3E0
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
movq $0x0, -0x20(%rbp)
cmpq $0x0, -0x10(%rbp)
jbe 0x77e50
movq -0x8(%rbp), %rdi
callq 0x52c60
testb $0x1, %al
jne 0x77683
movl $0x10, %edi
callq 0x82f0
movq %rax, %rdi
movq %rdi, %rax
movq %rax, -0x2e8(%rbp)
leaq 0x6baf(%rip), %rsi      # 0x7e1f4
callq 0x8220
jmp 0x7764c
movq -0x2e8(%rbp), %rdi
movq 0x37996(%rip), %rsi     # 0xaeff0
movq 0x3790f(%rip), %rdx     # 0xaef70
callq 0x8b70
movq -0x2e8(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x28(%rbp)
movl %eax, -0x2c(%rbp)
callq 0x8490
jmp 0x77e5d
movq -0x8(%rbp), %rsi
movq -0x10(%rbp), %rdx
leaq -0xa0(%rbp), %rdi
callq 0x52c80
leaq -0xa0(%rbp), %rdi
callq 0x52d70
movq %rax, -0xa8(%rbp)
cmpq $0x0, -0xa8(%rbp)
jne 0x776b9
jmp 0x77e50
movq -0xa8(%rbp), %rcx
movq -0x8(%rbp), %rax
addq %rcx, %rax
movq %rax, -0x8(%rbp)
movq -0xa8(%rbp), %rcx
movq -0x10(%rbp), %rax
subq %rcx, %rax
movq %rax, -0x10(%rbp)
movq -0xa8(%rbp), %rcx
movq -0x20(%rbp), %rax
addq %rcx, %rax
movq %rax, -0x20(%rbp)
xorl %eax, %eax
movl %eax, %esi
movq %rsi, -0x2f8(%rbp)
leaq -0xd8(%rbp), %rdi
callq 0x50be0
movq -0x2f8(%rbp), %rsi
leaq -0xf8(%rbp), %rdi
callq 0x50880
leaq -0xa0(%rbp), %rdi
callq 0x50bc0
movb %al, %cl
movb %cl, -0x2e9(%rbp)
subb $0x11, %al
je 0x77756
jmp 0x77733
movb -0x2e9(%rbp), %al
subb $0x14, %al
je 0x77b7a
jmp 0x77743
movb -0x2e9(%rbp), %al
subb $0x1c, %al
je 0x77981
jmp 0x77d85
leaq -0xa0(%rbp), %rax
movq %rax, -0x310(%rbp)
movq %rax, -0x100(%rbp)
leaq -0xd8(%rbp), %rdi
leaq -0x100(%rbp), %rsi
callq 0x77e70
movq -0x310(%rbp), %rax
movq %rax, -0x108(%rbp)
leaq -0xf8(%rbp), %rdi
leaq -0x108(%rbp), %rsi
callq 0x77ec0
movq -0x310(%rbp), %rsi
leaq -0x118(%rbp), %rdi
movq %rdi, -0x300(%rbp)
callq 0x50ce0
leaq -0x128(%rbp), %rdi
movq %rdi, -0x308(%rbp)
leaq -0xb0(%rbp), %rsi
leaq -0xb8(%rbp), %rdx
callq 0x50d10
movq -0x308(%rbp), %rdi
movq -0x300(%rbp), %rsi
callq 0x50d50
leaq -0x138(%rbp), %rdi
callq 0xded0
jmp 0x777fb
leaq 0x6a0b(%rip), %rsi      # 0x7e20d
leaq -0x138(%rbp), %rdi
callq 0x2cd60
movq %rax, -0x318(%rbp)
jmp 0x77817
movq -0xb0(%rbp), %rax
movq %rax, -0x330(%rbp)
movq -0xb8(%rbp), %rax
movq %rax, -0x328(%rbp)
leaq -0x159(%rbp), %rdi
movq %rdi, -0x320(%rbp)
callq 0x8bd0
movq -0x330(%rbp), %rsi
movq -0x328(%rbp), %rdx
movq -0x320(%rbp), %rcx
leaq -0x158(%rbp), %rdi
callq 0x8700
jmp 0x77869
movq -0x318(%rbp), %rdi
leaq -0x158(%rbp), %rsi
callq 0xa690
jmp 0x7787e
leaq -0x158(%rbp), %rdi
callq 0x83f0
leaq -0x159(%rbp), %rdi
callq 0x86a0
leaq -0x138(%rbp), %rdi
callq 0xa770
movq -0x18(%rbp), %rax
movq %rax, -0x340(%rbp)
movq -0xb0(%rbp), %rsi
movq -0xb8(%rbp), %rdx
leaq -0x190(%rbp), %rdi
movq %rdi, -0x338(%rbp)
callq 0x32ae0
movq -0x340(%rbp), %rdi
movq -0x338(%rbp), %rsi
leaq -0xd8(%rbp), %rdx
leaq -0xf8(%rbp), %rcx
callq 0x78e80
jmp 0x778f1
leaq -0x190(%rbp), %rdi
callq 0x2ecf0
jmp 0x77e01
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x28(%rbp)
movl %eax, -0x2c(%rbp)
jmp 0x77e36
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x28(%rbp)
movl %eax, -0x2c(%rbp)
jmp 0x77953
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x28(%rbp)
movl %eax, -0x2c(%rbp)
jmp 0x77947
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x28(%rbp)
movl %eax, -0x2c(%rbp)
leaq -0x158(%rbp), %rdi
callq 0x83f0
leaq -0x159(%rbp), %rdi
callq 0x86a0
leaq -0x138(%rbp), %rdi
callq 0xa770
jmp 0x77e36
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x28(%rbp)
movl %eax, -0x2c(%rbp)
leaq -0x190(%rbp), %rdi
callq 0x2ecf0
jmp 0x77e36
leaq -0xa0(%rbp), %rax
movq %rax, -0x358(%rbp)
movq %rax, -0x198(%rbp)
leaq -0xd8(%rbp), %rdi
leaq -0x198(%rbp), %rsi
callq 0x77f10
movq -0x358(%rbp), %rsi
leaq -0x1a8(%rbp), %rdi
movq %rdi, -0x348(%rbp)
callq 0x50ce0
leaq -0x1b8(%rbp), %rdi
movq %rdi, -0x350(%rbp)
leaq -0xb0(%rbp), %rsi
leaq -0xb8(%rbp), %rdx
callq 0x50d10
movq -0x350(%rbp), %rdi
movq -0x348(%rbp), %rsi
callq 0x50d50
leaq -0x1c8(%rbp), %rdi
callq 0xded0
jmp 0x77a05
leaq 0x680c(%rip), %rsi      # 0x7e218
leaq -0x1c8(%rbp), %rdi
callq 0x57f20
movq %rax, -0x360(%rbp)
jmp 0x77a21
movq -0xb0(%rbp), %rax
movq %rax, -0x378(%rbp)
movq -0xb8(%rbp), %rax
movq %rax, -0x370(%rbp)
leaq -0x1e9(%rbp), %rdi
movq %rdi, -0x368(%rbp)
callq 0x8bd0
movq -0x378(%rbp), %rsi
movq -0x370(%rbp), %rdx
movq -0x368(%rbp), %rcx
leaq -0x1e8(%rbp), %rdi
callq 0x8700
jmp 0x77a73
movq -0x360(%rbp), %rdi
leaq -0x1e8(%rbp), %rsi
callq 0xa690
jmp 0x77a88
leaq -0x1e8(%rbp), %rdi
callq 0x83f0
leaq -0x1e9(%rbp), %rdi
callq 0x86a0
leaq -0x1c8(%rbp), %rdi
callq 0xa770
movq -0x18(%rbp), %rax
movq %rax, -0x388(%rbp)
movq -0xb0(%rbp), %rsi
movq -0xb8(%rbp), %rdx
leaq -0x220(%rbp), %rdi
movq %rdi, -0x380(%rbp)
callq 0x32ae0
movq -0x388(%rbp), %rdi
movq -0x380(%rbp), %rsi
leaq -0xd8(%rbp), %rdx
leaq -0xf8(%rbp), %rcx
callq 0x78e80
jmp 0x77afb
leaq -0x220(%rbp), %rdi
callq 0x2ecf0
jmp 0x77e01
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x28(%rbp)
movl %eax, -0x2c(%rbp)
jmp 0x77b4c
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x28(%rbp)
movl %eax, -0x2c(%rbp)
jmp 0x77b40
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x28(%rbp)
movl %eax, -0x2c(%rbp)
leaq -0x1e8(%rbp), %rdi
callq 0x83f0
leaq -0x1e9(%rbp), %rdi
callq 0x86a0
leaq -0x1c8(%rbp), %rdi
callq 0xa770
jmp 0x77e36
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x28(%rbp)
movl %eax, -0x2c(%rbp)
leaq -0x220(%rbp), %rdi
callq 0x2ecf0
jmp 0x77e36
leaq -0x230(%rbp), %rdi
movq %rdi, -0x390(%rbp)
leaq -0xa0(%rbp), %rsi
callq 0x50ce0
leaq -0x240(%rbp), %rdi
movq %rdi, -0x398(%rbp)
leaq -0xb0(%rbp), %rsi
leaq -0xb8(%rbp), %rdx
callq 0x50d10
movq -0x398(%rbp), %rdi
movq -0x390(%rbp), %rsi
callq 0x50d50
leaq -0x250(%rbp), %rdi
callq 0xded0
jmp 0x77bd6
leaq 0x6648(%rip), %rsi      # 0x7e225
leaq -0x250(%rbp), %rdi
callq 0x3a9c0
movq %rax, -0x3a0(%rbp)
jmp 0x77bf2
movq -0xb0(%rbp), %rax
movq %rax, -0x3b8(%rbp)
movq -0xb8(%rbp), %rax
movq %rax, -0x3b0(%rbp)
leaq -0x271(%rbp), %rdi
movq %rdi, -0x3a8(%rbp)
callq 0x8bd0
movq -0x3b8(%rbp), %rsi
movq -0x3b0(%rbp), %rdx
movq -0x3a8(%rbp), %rcx
leaq -0x270(%rbp), %rdi
callq 0x8700
jmp 0x77c44
movq -0x3a0(%rbp), %rdi
leaq -0x270(%rbp), %rsi
callq 0xa690
jmp 0x77c59
leaq -0x270(%rbp), %rdi
callq 0x83f0
leaq -0x271(%rbp), %rdi
callq 0x86a0
leaq -0x250(%rbp), %rdi
callq 0xa770
leaq 0x3837c(%rip), %rax     # 0xb0000
movq 0x78(%rax), %rcx
incq %rcx
movq %rcx, 0x78(%rax)
movq -0x18(%rbp), %rax
movq %rax, -0x3d0(%rbp)
movq -0xb0(%rbp), %rsi
movq -0xb8(%rbp), %rdx
leaq -0x2a8(%rbp), %rdi
movq %rdi, -0x3c8(%rbp)
callq 0x32ae0
xorl %eax, %eax
movl %eax, %esi
leaq -0x2c8(%rbp), %rdi
movq %rdi, -0x3c0(%rbp)
callq 0x50c20
movq -0x3d0(%rbp), %rdi
movq -0x3c8(%rbp), %rsi
movq -0x3c0(%rbp), %rdx
callq 0x78ed0
jmp 0x77cee
leaq -0x2c8(%rbp), %rdi
callq 0x51080
leaq -0x2a8(%rbp), %rdi
callq 0x2ecf0
jmp 0x77e01
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x28(%rbp)
movl %eax, -0x2c(%rbp)
jmp 0x77d4b
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x28(%rbp)
movl %eax, -0x2c(%rbp)
jmp 0x77d3f
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x28(%rbp)
movl %eax, -0x2c(%rbp)
leaq -0x270(%rbp), %rdi
callq 0x83f0
leaq -0x271(%rbp), %rdi
callq 0x86a0
leaq -0x250(%rbp), %rdi
callq 0xa770
jmp 0x77e36
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x28(%rbp)
movl %eax, -0x2c(%rbp)
leaq -0x2c8(%rbp), %rdi
callq 0x51080
leaq -0x2a8(%rbp), %rdi
callq 0x2ecf0
jmp 0x77e36
leaq -0x2d8(%rbp), %rdi
callq 0xa600
jmp 0x77d93
leaq 0x6499(%rip), %rsi      # 0x7e233
leaq -0x2d8(%rbp), %rdi
callq 0x223e0
movq %rax, -0x3d8(%rbp)
jmp 0x77daf
movq -0x3d8(%rbp), %rdi
leaq 0x1193(%rip), %rsi      # 0x78f50
callq 0x78f10
movq %rax, -0x3e0(%rbp)
jmp 0x77dcb
leaq -0xa0(%rbp), %rdi
callq 0x50bc0
movq -0x3e0(%rbp), %rdi
movzbl %al, %eax
movl %eax, -0x2dc(%rbp)
leaq -0x2dc(%rbp), %rsi
callq 0x24620
jmp 0x77df5
leaq -0x2d8(%rbp), %rdi
callq 0xa770
leaq -0xf8(%rbp), %rdi
callq 0x508c0
leaq -0xd8(%rbp), %rdi
callq 0x508e0
jmp 0x7760f
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x28(%rbp)
movl %eax, -0x2c(%rbp)
leaq -0x2d8(%rbp), %rdi
callq 0xa770
leaq -0xf8(%rbp), %rdi
callq 0x508c0
leaq -0xd8(%rbp), %rdi
callq 0x508e0
jmp 0x77e5d
movq -0x20(%rbp), %rax
addq $0x3e0, %rsp            # imm = 0x3E0
popq %rbp
retq
movq -0x28(%rbp), %rdi
callq 0x8bc0
nopw %cs:(%rax,%rax)