RZ

001: // LocalScan.hh # the actual synthesize algorithm
002:
003: #ifndef _LocalScan_HH
004: #define _LocalScan_HH 1
005:
006: #include <unistd.h>
007: #include <sys/uio.h>
008: #include <sys/stat.h>
009: #include <sys/mman.h>
010:
011: #include "RZError.hh"
012: #include "RZNetOrder.hh"
013: #include "RZIO.hh"
014: #include "RZMagic.hh"
015: #include "ExtractLocalLookup.hh"
016: #include "ExtractIntermediate.hh"
017: #include "MMap.hh"
018:
019: namespace RZ {
020:     struct Scanner;
021: }
022:
023: // #### Scan given streams using 96 bits of signature for local blocks ####
024:
025: struct RZ::Scanner: RZ::LocalSums, RZ::LookupTable {
026:     int const local_fd;
027:     char volatile * const ltab_mmap;
028:     char const volatile * const rtab_mmap;
029:
030:     Scanner(
031:         int const localfd, struct RZWrapper const &rzwrapper,
032:         char volatile * const l, char const volatile * const r)
033:     :
034:         LocalSums(rzwrapper),
035:         LookupTable(rzwrapper.signature_table),
036:         local_fd(localfd),
037:         ltab_mmap(l),
038:         rtab_mmap(r)
039:     {}
040:
041:     Scanner(
042:         int const localfd, struct IntermediateWrapper const &interwrap,
043:         int const ltabfd, int const rtabfd)
044:     :
045:         LocalSums(interwrap),
046:         LookupTable(interwrap.n_blks, interwrap.RZ_WRAPPER),
047:         local_fd(localfd),
048:         ltab_mmap(
049:             fd_memory_map(ltabfd, interwrap.n_blks, true, "local blocks")),
050:         rtab_mmap(
051:             fd_memory_map(rtabfd, interwrap.n_blks, false, "remote blocks"))
052:     {}
053:
054:     inline bool has_more(Range const range)
055:     {
056:         for (Lookup::iterator r = range.first; r < range.second; ++r)
057:             if (!ltab_mmap[ r->bk_i ] && !rtab_mmap[ r->bk_i ]) return true;
058:         return false;
059:     }
060:
061:     inline bool check_more(Range const range, char * const back)
062:     {
063:         for (Lookup::iterator r = range.first; r < range.second; ++r) {
064:             if (ltab_mmap[ r->bk_i ] || rtab_mmap[ r->bk_i ]) continue;
065:             if (a.checksum32(back) != r->sig_a) continue;
066:             if (b.checksum32(back) != r->sig_b) continue;
067:             ltab_mmap[ r->bk_i ] = -1;
068:
069:             struct iovec output[2];
070:             char bkhint[4];
071:             net_out(bkhint, r->bk_i);
072:             output[0].iov_base = bkhint;
073:             output[0].iov_len = 4;
074:             output[1].iov_base = back;
075:             output[1].iov_len = block_size;
076:             fd_writev(local_fd, output, 2);
077:
078:             return true;
079:         }
080:         return false;
081:     }
082:
083:     inline bool check_more(Range const range,
084:         char * const back0, unsigned int const len0, char * const back1)
085:     {
086:         for (Lookup::iterator r = range.first; r < range.second; ++r) {
087:             if (ltab_mmap[ r->bk_i ] || rtab_mmap[ r->bk_i ]) continue;
088:             if (a.checksum32(back0, len0, back1) != r->sig_a) continue;
089:             if (b.checksum32(back0, len0, back1) != r->sig_b) continue;
090:             ltab_mmap[ r->bk_i ] = -1;
091:
092:             struct iovec output[3];
093:             char bkhint[4];
094:             net_out(bkhint, r->bk_i);
095:             output[0].iov_base = bkhint;
096:             output[0].iov_len = 4;
097:             output[1].iov_base = back0;
098:             output[1].iov_len = len0;
099:             output[2].iov_base = back1;
100:             output[2].iov_len = block_size - len0;
101:             fd_writev(local_fd, output, 3);
102:
103:             return true;
104:         }
105:         return false;
106:     }
107:
108:     void scan_mmap(int givenfd);
109:     void scan_stream(int givenfd);
110:     void scan_circular(int givenfd);
111: };
112:
113: // ######## ######## ######## ######## ######## ######## ######## ########
114:
115: // LocalScan.hh # the actual synthesize algorithm
116:
117: #endif