// File: Infinidat[P]slimfastq/recs.cpp
// Function: RecSave::save(unsigned char const*, unsigned char const*, unsigned char const*, unsigned char const*)
void RecSave::save(const UCHAR* buf, const UCHAR* end, const UCHAR* prev_buf, const UCHAR* prev_end) {

    rarely_if(not m_last.initilized) {
        imap = 0;
        save_first_line(buf, end);
        map_space(buf, imap);
        bzero(ctype[0], sizeof(ctype[0])); // clear cache
        bzero(ctype[1], sizeof(ctype[1])); // clear cache
        return;
    }
    bool pmap = imap;
    imap = imap ? 0 : 1;
    map_space(buf, imap);

    rarely_if (smap[imap].len != smap[pmap].len or
               memcmp(smap[imap].str, smap[pmap].str, smap[imap].len)) {
        // Too bad, new kind of header
        // must push to extension file

        x_file->put(g_record_count - m_last.index);
        m_last.index = g_record_count;
        x_file->put_str(buf, end-buf);
        bzero(ctype[imap], sizeof(ctype[imap])); // clear cache

        stats.new_n ++ ;
        stats.new_l += end-buf;
        return;
    }

    UINT64 map = 0;
    for (int i = 0; i < smap[imap].len; i ++)
        if ( smap[imap].wln[i] != smap[pmap].wln[i] or
             memcmp(buf + smap[imap].off[i], prev_buf + smap[pmap].off[i], smap[imap].wln[i]))
            DO_SET(map, i);

    put_num (0, map);           // mapping of changes. (zero could have meant copy prev)

    for (int i = 0; i < smap[0].len; i++) {
        if (IS_SET(map, i)) {

            // int i = BFIRST(map)-1;
            // DO_CLR(map, i);
            const UCHAR* b = buf + smap[imap].off[i];
            // const UCHAR* p = prev_buf + smap[pmap].off[i];
            UINT64 bnum;

            UCHAR type = numberwang(b, smap[imap].wln[i], bnum, ctype[pmap][i]);
            if  ( type == ST_STR) {
                put_type(i+1, type);
                put_str (i+1, b, smap[imap].wln[i]);
                stats.str_n ++ ;
                stats.str_l += smap[imap].wln[i];
                ctype[imap][i] = 0; // NAN
                continue;
            }
            // HERE: this is a number
            UINT64 pnum = ctype[pmap][i] ? cnumb[pmap][i] : 0;
            UINT64 gap ;

            ctype[imap][i] = (type < ST_STR or type >= ST_DGT_Z) ? 1 : 2;
            cnumb[imap][i] = bnum;

            if (bnum < pnum) {
                gap  = pnum - bnum;
                type ++ ;
            }
            else
                gap  = bnum - pnum;

            put_type(i+1, type);
            put_num (i+1, gap);

            //     if (is_number(b, smap[imap].wln[i], bnum) and
            //         is_number(p, smap[pmap].wln[i], pnum)) {
            //         if (bnum > pnum) {
            //             put_type(i+1, ST_DGT);
            //             put_num (i+1, bnum - pnum);
            //         }
            //         else {
            //             put_type(i+1, ST_DLT);
            //             put_num (i+1, pnum - bnum);
            //         }
            //     }
            //     else {
            //         put_type(i+1, ST_STR);
            //         put_str (i+1, b, smap[imap].wln[i]);
            //         stats.str_n ++ ;
            //         stats.str_l += smap[imap].wln[i];
            //     }
        }
        else {
            ctype[imap][i] = ctype[pmap][i];
            cnumb[imap][i] = cnumb[pmap][i];
        }
    }
}

// Assembly:
subq $0x98, %rsp
movq %rdi, 0x90(%rsp)
movq %rsi, 0x88(%rsp)
movq %rdx, 0x80(%rsp)
movq %rcx, 0x78(%rsp)
movq %r8, 0x70(%rsp)
movq 0x90(%rsp), %rax
movq %rax, 0x28(%rsp)
movb 0xc7d08(%rax), %al
xorb $-0x1, %al
testb $0x1, %al
jne 0xaea4
jmp 0xaf1b
movq 0x28(%rsp), %rdi
movb $0x0, 0xc8660(%rdi)
movq 0x88(%rsp), %rsi
movq 0x80(%rsp), %rdx
callq 0xa630
movq 0x28(%rsp), %rdi
movq 0x88(%rsp), %rsi
movb 0xc8660(%rdi), %al
andb $0x1, %al
movzbl %al, %edx
callq 0xabb0
movq 0x28(%rsp), %rdi
addq $0xc81c8, %rdi          # imm = 0xC81C8
xorl %esi, %esi
movl $0x41, %edx
callq 0x2170
movq 0x28(%rsp), %rdi
addq $0xc81c8, %rdi          # imm = 0xC81C8
addq $0x41, %rdi
xorl %esi, %esi
movl $0x41, %edx
callq 0x2170
jmp 0xb678
movq 0x28(%rsp), %rdi
movb 0xc8660(%rdi), %al
andb $0x1, %al
movb %al, 0x6f(%rsp)
movb 0xc8660(%rdi), %dl
movl $0x1, %eax
xorl %ecx, %ecx
testb $0x1, %dl
cmovnel %ecx, %eax
cmpl $0x0, %eax
setne %al
andb $0x1, %al
movb %al, 0xc8660(%rdi)
movq 0x88(%rsp), %rsi
movb 0xc8660(%rdi), %al
andb $0x1, %al
movzbl %al, %edx
callq 0xabb0
movq 0x28(%rsp), %rax
movq %rax, %rcx
addq $0xc7d30, %rcx          # imm = 0xC7D30
movb 0xc8660(%rax), %dl
andb $0x1, %dl
movzbl %dl, %edx
imulq $0x24c, %rdx, %rdx      # imm = 0x24C
addq %rdx, %rcx
movzbl 0x249(%rcx), %ecx
addq $0xc7d30, %rax          # imm = 0xC7D30
movb 0x6f(%rsp), %dl
andb $0x1, %dl
movzbl %dl, %edx
imulq $0x24c, %rdx, %rdx      # imm = 0x24C
addq %rdx, %rax
movzbl 0x249(%rax), %edx
movb $0x1, %al
cmpl %edx, %ecx
movb %al, 0x27(%rsp)
jne 0xb046
movq 0x28(%rsp), %rcx
movq %rcx, %rdi
addq $0xc7d30, %rdi          # imm = 0xC7D30
movb 0xc8660(%rcx), %al
andb $0x1, %al
movzbl %al, %eax
imulq $0x24c, %rax, %rax      # imm = 0x24C
addq %rax, %rdi
addq $0x208, %rdi            # imm = 0x208
movq %rcx, %rsi
addq $0xc7d30, %rsi          # imm = 0xC7D30
movb 0x6f(%rsp), %al
andb $0x1, %al
movzbl %al, %eax
imulq $0x24c, %rax, %rax      # imm = 0x24C
addq %rax, %rsi
addq $0x208, %rsi            # imm = 0x208
movq %rcx, %rax
addq $0xc7d30, %rax          # imm = 0xC7D30
movb 0xc8660(%rcx), %cl
andb $0x1, %cl
movzbl %cl, %ecx
imulq $0x24c, %rcx, %rcx      # imm = 0x24C
addq %rcx, %rax
movzbl 0x249(%rax), %eax
movl %eax, %edx
callq 0x2140
cmpl $0x0, %eax
setne %al
movb %al, 0x27(%rsp)
movb 0x27(%rsp), %al
testb $0x1, %al
jne 0xb053
jmp 0xb11a
movq 0x28(%rsp), %rax
movq 0xc8670(%rax), %rdi
leaq 0xb1fa(%rip), %rcx      # 0x16260
movq (%rcx), %rsi
subq 0xc7d10(%rax), %rsi
callq 0xf7a0
movq 0x28(%rsp), %rax
leaq 0xb1df(%rip), %rcx      # 0x16260
movq (%rcx), %rcx
movq %rcx, 0xc7d10(%rax)
movq 0xc8670(%rax), %rdi
movq 0x88(%rsp), %rsi
movq 0x80(%rsp), %rdx
movq 0x88(%rsp), %rax
subq %rax, %rdx
callq 0xfbd0
movq 0x28(%rsp), %rax
movq %rax, %rdi
addq $0xc81c8, %rdi          # imm = 0xC81C8
movb 0xc8660(%rax), %al
andb $0x1, %al
movzbl %al, %eax
imulq $0x41, %rax, %rax
addq %rax, %rdi
xorl %esi, %esi
movl $0x41, %edx
callq 0x2170
movq 0x28(%rsp), %rax
movl 0xc7d24(%rax), %ecx
addl $0x1, %ecx
movl %ecx, 0xc7d24(%rax)
movq 0x80(%rsp), %rdx
movq 0x88(%rsp), %rcx
subq %rcx, %rdx
movl 0xc7d28(%rax), %ecx
addq %rdx, %rcx
movl %ecx, 0xc7d28(%rax)
jmp 0xb678
movq $0x0, 0x60(%rsp)
movl $0x0, 0x5c(%rsp)
movq 0x28(%rsp), %rdx
movl 0x5c(%rsp), %eax
movq %rdx, %rcx
addq $0xc7d30, %rcx          # imm = 0xC7D30
movb 0xc8660(%rdx), %dl
andb $0x1, %dl
movzbl %dl, %edx
imulq $0x24c, %rdx, %rdx      # imm = 0x24C
addq %rdx, %rcx
movzbl 0x249(%rcx), %ecx
cmpl %ecx, %eax
jge 0xb286
movq 0x28(%rsp), %rcx
movq %rcx, %rax
addq $0xc7d30, %rax          # imm = 0xC7D30
movb 0xc8660(%rcx), %dl
andb $0x1, %dl
movzbl %dl, %edx
imulq $0x24c, %rdx, %rdx      # imm = 0x24C
addq %rdx, %rax
movslq 0x5c(%rsp), %rdx
movl 0x104(%rax,%rdx,4), %eax
addq $0xc7d30, %rcx          # imm = 0xC7D30
movb 0x6f(%rsp), %dl
andb $0x1, %dl
movzbl %dl, %edx
imulq $0x24c, %rdx, %rdx      # imm = 0x24C
addq %rdx, %rcx
movslq 0x5c(%rsp), %rdx
cmpl 0x104(%rcx,%rdx,4), %eax
jne 0xb25c
movq 0x28(%rsp), %rcx
movq 0x88(%rsp), %rdi
movq %rcx, %rax
addq $0xc7d30, %rax          # imm = 0xC7D30
movb 0xc8660(%rcx), %dl
andb $0x1, %dl
movzbl %dl, %edx
imulq $0x24c, %rdx, %rdx      # imm = 0x24C
addq %rdx, %rax
movslq 0x5c(%rsp), %rdx
movslq (%rax,%rdx,4), %rax
addq %rax, %rdi
movq 0x78(%rsp), %rsi
movq %rcx, %rax
addq $0xc7d30, %rax          # imm = 0xC7D30
movb 0x6f(%rsp), %dl
andb $0x1, %dl
movzbl %dl, %edx
imulq $0x24c, %rdx, %rdx      # imm = 0x24C
addq %rdx, %rax
movslq 0x5c(%rsp), %rdx
movslq (%rax,%rdx,4), %rax
addq %rax, %rsi
movq %rcx, %rax
addq $0xc7d30, %rax          # imm = 0xC7D30
movb 0xc8660(%rcx), %cl
andb $0x1, %cl
movzbl %cl, %ecx
imulq $0x24c, %rcx, %rcx      # imm = 0x24C
addq %rcx, %rax
movslq 0x5c(%rsp), %rcx
movslq 0x104(%rax,%rcx,4), %rdx
callq 0x2140
cmpl $0x0, %eax
je 0xb274
movl 0x5c(%rsp), %eax
movl %eax, %ecx
movl $0x1, %eax
shlq %cl, %rax
orq 0x60(%rsp), %rax
movq %rax, 0x60(%rsp)
jmp 0xb276
movl 0x5c(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x5c(%rsp)
jmp 0xb12b
movq 0x28(%rsp), %rdi
movq 0x60(%rsp), %rdx
xorl %esi, %esi
callq 0xa760
movl $0x0, 0x58(%rsp)
movq 0x28(%rsp), %rcx
movl 0x58(%rsp), %eax
movzbl 0xc7f79(%rcx), %ecx
cmpl %ecx, %eax
jge 0xb678
movq 0x60(%rsp), %rax
movq %rax, 0x18(%rsp)
movl 0x58(%rsp), %eax
movl %eax, %ecx
movl $0x1, %eax
shlq %cl, %rax
movq 0x18(%rsp), %rcx
andq %rax, %rcx
xorl %eax, %eax
cmpq %rcx, %rax
je 0xb5cb
movq 0x28(%rsp), %rax
movq 0x88(%rsp), %rcx
movq %rax, %rdx
addq $0xc7d30, %rdx          # imm = 0xC7D30
movb 0xc8660(%rax), %sil
andb $0x1, %sil
movzbl %sil, %esi
imulq $0x24c, %rsi, %rsi      # imm = 0x24C
addq %rsi, %rdx
movslq 0x58(%rsp), %rsi
movslq (%rdx,%rsi,4), %rdx
addq %rdx, %rcx
movq %rcx, 0x50(%rsp)
movq 0x50(%rsp), %rdi
movq %rax, %rcx
addq $0xc7d30, %rcx          # imm = 0xC7D30
movb 0xc8660(%rax), %dl
andb $0x1, %dl
movzbl %dl, %edx
imulq $0x24c, %rdx, %rdx      # imm = 0x24C
addq %rdx, %rcx
movslq 0x58(%rsp), %rdx
movl 0x104(%rcx,%rdx,4), %esi
addq $0xc81c8, %rax          # imm = 0xC81C8
movb 0x6f(%rsp), %cl
andb $0x1, %cl
movzbl %cl, %ecx
imulq $0x41, %rcx, %rcx
addq %rcx, %rax
movslq 0x58(%rsp), %rcx
leaq 0x48(%rsp), %rdx
movzbl (%rax,%rcx), %ecx
callq 0xb680
movb %al, 0x47(%rsp)
movzbl 0x47(%rsp), %eax
cmpl $0x2, %eax
jne 0xb466
movq 0x28(%rsp), %rdi
movl 0x58(%rsp), %eax
addl $0x1, %eax
movzbl %al, %esi
movzbl 0x47(%rsp), %edx
callq 0xa7d0
movq 0x28(%rsp), %rdi
movl 0x58(%rsp), %eax
addl $0x1, %eax
movq 0x50(%rsp), %rdx
movq %rdi, %rcx
addq $0xc7d30, %rcx          # imm = 0xC7D30
movb 0xc8660(%rdi), %sil
andb $0x1, %sil
movzbl %sil, %esi
imulq $0x24c, %rsi, %rsi      # imm = 0x24C
addq %rsi, %rcx
movslq 0x58(%rsp), %rsi
movl 0x104(%rcx,%rsi,4), %ecx
movzbl %al, %esi
callq 0xa6b0
movq 0x28(%rsp), %rcx
movl 0xc7d1c(%rcx), %eax
addl $0x1, %eax
movl %eax, 0xc7d1c(%rcx)
movq %rcx, %rax
addq $0xc7d30, %rax          # imm = 0xC7D30
movb 0xc8660(%rcx), %dl
andb $0x1, %dl
movzbl %dl, %edx
imulq $0x24c, %rdx, %rdx      # imm = 0x24C
addq %rdx, %rax
movslq 0x58(%rsp), %rdx
movl 0x104(%rax,%rdx,4), %eax
addl 0xc7d20(%rcx), %eax
movl %eax, 0xc7d20(%rcx)
movq %rcx, %rax
addq $0xc81c8, %rax          # imm = 0xC81C8
movb 0xc8660(%rcx), %cl
andb $0x1, %cl
movzbl %cl, %ecx
imulq $0x41, %rcx, %rcx
addq %rcx, %rax
movslq 0x58(%rsp), %rcx
movb $0x0, (%rax,%rcx)
jmp 0xb668
movq 0x28(%rsp), %rax
addq $0xc81c8, %rax          # imm = 0xC81C8
movb 0x6f(%rsp), %cl
andb $0x1, %cl
movzbl %cl, %ecx
imulq $0x41, %rcx, %rcx
addq %rcx, %rax
movslq 0x58(%rsp), %rcx
cmpb $0x0, (%rax,%rcx)
je 0xb4bc
movq 0x28(%rsp), %rax
addq $0xc8250, %rax          # imm = 0xC8250
movb 0x6f(%rsp), %cl
andb $0x1, %cl
movzbl %cl, %ecx
imulq $0x208, %rcx, %rcx      # imm = 0x208
addq %rcx, %rax
movslq 0x58(%rsp), %rcx
movq (%rax,%rcx,8), %rax
movq %rax, 0x10(%rsp)
jmp 0xb4c5
xorl %eax, %eax
movq %rax, 0x10(%rsp)
jmp 0xb4c5
movq 0x10(%rsp), %rax
movq %rax, 0x38(%rsp)
movzbl 0x47(%rsp), %ecx
movb $0x1, %al
cmpl $0x2, %ecx
movb %al, 0xf(%rsp)
jl 0xb4ee
movzbl 0x47(%rsp), %eax
cmpl $0xb, %eax
setge %al
movb %al, 0xf(%rsp)
movq 0x28(%rsp), %rcx
movb 0xf(%rsp), %sil
movl $0x2, %eax
movl $0x1, %edx
testb $0x1, %sil
cmovnel %edx, %eax
movb %al, %sil
movq %rcx, %rax
addq $0xc81c8, %rax          # imm = 0xC81C8
movb 0xc8660(%rcx), %dl
andb $0x1, %dl
movzbl %dl, %edx
imulq $0x41, %rdx, %rdx
addq %rdx, %rax
movslq 0x58(%rsp), %rdx
movb %sil, (%rax,%rdx)
movq 0x48(%rsp), %rdx
movq %rcx, %rax
addq $0xc8250, %rax          # imm = 0xC8250
movb 0xc8660(%rcx), %cl
andb $0x1, %cl
movzbl %cl, %ecx
imulq $0x208, %rcx, %rcx      # imm = 0x208
addq %rcx, %rax
movslq 0x58(%rsp), %rcx
movq %rdx, (%rax,%rcx,8)
movq 0x48(%rsp), %rax
cmpq 0x38(%rsp), %rax
jae 0xb585
movq 0x38(%rsp), %rax
subq 0x48(%rsp), %rax
movq %rax, 0x30(%rsp)
movb 0x47(%rsp), %al
addb $0x1, %al
movb %al, 0x47(%rsp)
jmp 0xb594
movq 0x48(%rsp), %rax
subq 0x38(%rsp), %rax
movq %rax, 0x30(%rsp)
movq 0x28(%rsp), %rdi
movl 0x58(%rsp), %eax
addl $0x1, %eax
movzbl %al, %esi
movzbl 0x47(%rsp), %edx
callq 0xa7d0
movq 0x28(%rsp), %rdi
movl 0x58(%rsp), %eax
addl $0x1, %eax
movq 0x30(%rsp), %rdx
movzbl %al, %esi
callq 0xa760
jmp 0xb666
movq 0x28(%rsp), %rcx
movq %rcx, %rax
addq $0xc81c8, %rax          # imm = 0xC81C8
movb 0x6f(%rsp), %dl
andb $0x1, %dl
movzbl %dl, %edx
imulq $0x41, %rdx, %rdx
addq %rdx, %rax
movslq 0x58(%rsp), %rdx
movb (%rax,%rdx), %sil
movq %rcx, %rax
addq $0xc81c8, %rax          # imm = 0xC81C8
movb 0xc8660(%rcx), %dl
andb $0x1, %dl
movzbl %dl, %edx
imulq $0x41, %rdx, %rdx
addq %rdx, %rax
movslq 0x58(%rsp), %rdx
movb %sil, (%rax,%rdx)
movq %rcx, %rax
addq $0xc8250, %rax          # imm = 0xC8250
movb 0x6f(%rsp), %dl
andb $0x1, %dl
movzbl %dl, %edx
imulq $0x208, %rdx, %rdx      # imm = 0x208
addq %rdx, %rax
movslq 0x58(%rsp), %rdx
movq (%rax,%rdx,8), %rdx
movq %rcx, %rax
addq $0xc8250, %rax          # imm = 0xC8250
movb 0xc8660(%rcx), %cl
andb $0x1, %cl
movzbl %cl, %ecx
imulq $0x208, %rcx, %rcx      # imm = 0x208
addq %rcx, %rax
movslq 0x58(%rsp), %rcx
movq %rdx, (%rax,%rcx,8)
jmp 0xb668
movl 0x58(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x58(%rsp)
jmp 0xb29f
addq $0x98, %rsp
retq