\doxysubsection{delta.\+c}
\label{delta_8c_source}\index{delta.c@{delta.c}}
\mbox{\hyperlink{delta_8c}{Go to the documentation of this file.}}
\begin{DoxyCode}{0}
\DoxyCodeLine{00001 \textcolor{comment}{/*= -\/*-\/ c-\/basic-\/offset: 4; indent-\/tabs-\/mode: nil; -\/*-\/}}
\DoxyCodeLine{00002 \textcolor{comment}{ *}}
\DoxyCodeLine{00003 \textcolor{comment}{ * librsync -\/-\/ library for network deltas}}
\DoxyCodeLine{00004 \textcolor{comment}{ *}}
\DoxyCodeLine{00005 \textcolor{comment}{ * Copyright (C) 2000, 2001 by Martin Pool <mbp@sourcefrog.net>}}
\DoxyCodeLine{00006 \textcolor{comment}{ * Copyright (C) 2003 by Donovan Baarda <abo@minkirri.apana.org.au>}}
\DoxyCodeLine{00007 \textcolor{comment}{ *}}
\DoxyCodeLine{00008 \textcolor{comment}{ * This program is free software; you can redistribute it and/or modify}}
\DoxyCodeLine{00009 \textcolor{comment}{ * it under the terms of the GNU Lesser General Public License as published by}}
\DoxyCodeLine{00010 \textcolor{comment}{ * the Free Software Foundation; either version 2.1 of the License, or}}
\DoxyCodeLine{00011 \textcolor{comment}{ * (at your option) any later version.}}
\DoxyCodeLine{00012 \textcolor{comment}{ *}}
\DoxyCodeLine{00013 \textcolor{comment}{ * This program is distributed in the hope that it will be useful,}}
\DoxyCodeLine{00014 \textcolor{comment}{ * but WITHOUT ANY WARRANTY; without even the implied warranty of}}
\DoxyCodeLine{00015 \textcolor{comment}{ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the}}
\DoxyCodeLine{00016 \textcolor{comment}{ * GNU Lesser General Public License for more details.}}
\DoxyCodeLine{00017 \textcolor{comment}{ *}}
\DoxyCodeLine{00018 \textcolor{comment}{ * You should have received a copy of the GNU Lesser General Public License}}
\DoxyCodeLine{00019 \textcolor{comment}{ * along with this program; if not, write to the Free Software}}
\DoxyCodeLine{00020 \textcolor{comment}{ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.}}
\DoxyCodeLine{00021 \textcolor{comment}{ */}}
\DoxyCodeLine{00022 }
\DoxyCodeLine{00023                                 \textcolor{comment}{/*=}}
\DoxyCodeLine{00024 \textcolor{comment}{                                 | Let's climb to the TOP of that}}
\DoxyCodeLine{00025 \textcolor{comment}{                                 | MOUNTAIN and think about STRIP}}
\DoxyCodeLine{00026 \textcolor{comment}{                                 | MINING!!}}
\DoxyCodeLine{00027 \textcolor{comment}{                                 */}}
\DoxyCodeLine{00028 \textcolor{comment}{}}
\DoxyCodeLine{00029 \textcolor{comment}{/** \(\backslash\)file delta.c}}
\DoxyCodeLine{00030 \textcolor{comment}{ * Generate in streaming mode an rsync delta given a set of signatures, and a}}
\DoxyCodeLine{00031 \textcolor{comment}{ * new file.}}
\DoxyCodeLine{00032 \textcolor{comment}{ *}}
\DoxyCodeLine{00033 \textcolor{comment}{ * The size of blocks for signature generation is determined by the block size}}
\DoxyCodeLine{00034 \textcolor{comment}{ * in the incoming signature.}}
\DoxyCodeLine{00035 \textcolor{comment}{ *}}
\DoxyCodeLine{00036 \textcolor{comment}{ * To calculate a signature, we need to be able to see at least one block of}}
\DoxyCodeLine{00037 \textcolor{comment}{ * the new file at a time. Once we have that, we calculate its weak signature,}}
\DoxyCodeLine{00038 \textcolor{comment}{ * and see if there is any block in the signature hash table that has the same}}
\DoxyCodeLine{00039 \textcolor{comment}{ * weak sum. If there is one, then we also compute the strong sum of the new}}
\DoxyCodeLine{00040 \textcolor{comment}{ * block, and cross check that. If they're the same, then we can assume we have}}
\DoxyCodeLine{00041 \textcolor{comment}{ * a match.}}
\DoxyCodeLine{00042 \textcolor{comment}{ *}}
\DoxyCodeLine{00043 \textcolor{comment}{ * The final block of the file has to be handled a little differently, because}}
\DoxyCodeLine{00044 \textcolor{comment}{ * it may be a short match. Short blocks in the signature don't include their}}
\DoxyCodeLine{00045 \textcolor{comment}{ * length -\/-\/ we just allow for the final short block of the file to match any}}
\DoxyCodeLine{00046 \textcolor{comment}{ * block in the signature, and if they have the same checksum we assume they}}
\DoxyCodeLine{00047 \textcolor{comment}{ * must have the same length. Therefore, when we emit a COPY command, we have}}
\DoxyCodeLine{00048 \textcolor{comment}{ * to send it with a length that is the same as the block matched, and not the}}
\DoxyCodeLine{00049 \textcolor{comment}{ * block length from the signature.}}
\DoxyCodeLine{00050 \textcolor{comment}{ *}}
\DoxyCodeLine{00051 \textcolor{comment}{ * Profiling results as of v1.26, 2001-\/03-\/18:}}
\DoxyCodeLine{00052 \textcolor{comment}{ *}}
\DoxyCodeLine{00053 \textcolor{comment}{ * If everything matches, then we spend almost all our time in rs\_mdfour64 and}}
\DoxyCodeLine{00054 \textcolor{comment}{ * rs\_weak\_sum, which is unavoidable and therefore a good profile.}}
\DoxyCodeLine{00055 \textcolor{comment}{ *}}
\DoxyCodeLine{00056 \textcolor{comment}{ * If nothing matches, it is not so good.}}
\DoxyCodeLine{00057 \textcolor{comment}{ *}}
\DoxyCodeLine{00058 \textcolor{comment}{ * 2002-\/06-\/26: Donovan Baarda}}
\DoxyCodeLine{00059 \textcolor{comment}{ *}}
\DoxyCodeLine{00060 \textcolor{comment}{ * The following is based entirely on pysync. It is much cleaner than the}}
\DoxyCodeLine{00061 \textcolor{comment}{ * previous incarnation of this code. It is slightly complicated because in}}
\DoxyCodeLine{00062 \textcolor{comment}{ * this case the output can block, so the main delta loop needs to stop when}}
\DoxyCodeLine{00063 \textcolor{comment}{ * this happens.}}
\DoxyCodeLine{00064 \textcolor{comment}{ *}}
\DoxyCodeLine{00065 \textcolor{comment}{ * In pysync a 'last' attribute is used to hold the last miss or match for}}
\DoxyCodeLine{00066 \textcolor{comment}{ * extending if possible. In this code, basis\_len and scan\_pos are used instead}}
\DoxyCodeLine{00067 \textcolor{comment}{ * of 'last'. When basis\_len > 0, last is a match. When basis\_len = 0 and}}
\DoxyCodeLine{00068 \textcolor{comment}{ * scan\_pos is > 0, last is a miss. When both are 0, last is None (ie,}}
\DoxyCodeLine{00069 \textcolor{comment}{ * nothing).}}
\DoxyCodeLine{00070 \textcolor{comment}{ *}}
\DoxyCodeLine{00071 \textcolor{comment}{ * Pysync is also slightly different in that a 'flush' method is available to}}
\DoxyCodeLine{00072 \textcolor{comment}{ * force output of accumulated data. This 'flush' is use to finalise delta}}
\DoxyCodeLine{00073 \textcolor{comment}{ * calculation. In librsync input is terminated with an eof flag on the input}}
\DoxyCodeLine{00074 \textcolor{comment}{ * stream. I have structured this code similar to pysync with a seperate flush}}
\DoxyCodeLine{00075 \textcolor{comment}{ * function that is used when eof is reached. This allows for a flush style API}}
\DoxyCodeLine{00076 \textcolor{comment}{ * if one is ever needed. Note that flush in pysync can be used for more than}}
\DoxyCodeLine{00077 \textcolor{comment}{ * just terminating delta calculation, so a flush based API can in some ways be}}
\DoxyCodeLine{00078 \textcolor{comment}{ * more flexible...}}
\DoxyCodeLine{00079 \textcolor{comment}{ *}}
\DoxyCodeLine{00080 \textcolor{comment}{ * The input data is first scanned, then processed. Scanning identifies input}}
\DoxyCodeLine{00081 \textcolor{comment}{ * data as misses or matches, and emits the instruction stream. Processing the}}
\DoxyCodeLine{00082 \textcolor{comment}{ * data consumes it off the input scoop and outputs the processed miss data}}
\DoxyCodeLine{00083 \textcolor{comment}{ * into the tube.}}
\DoxyCodeLine{00084 \textcolor{comment}{ *}}
\DoxyCodeLine{00085 \textcolor{comment}{ * The scoop contains all data yet to be processed. The scan\_pos is an index}}
\DoxyCodeLine{00086 \textcolor{comment}{ * into the scoop that indicates the point scanned to. As data is scanned,}}
\DoxyCodeLine{00087 \textcolor{comment}{ * scan\_pos is incremented. As data is processed, it is removed from the scoop}}
\DoxyCodeLine{00088 \textcolor{comment}{ * and scan\_pos adjusted. Everything gets complicated because the tube can}}
\DoxyCodeLine{00089 \textcolor{comment}{ * block. When the tube is blocked, no data can be processed. */}}
\DoxyCodeLine{00090 }
\DoxyCodeLine{00091 \textcolor{preprocessor}{\#include "{}config.h"{}}             \textcolor{comment}{/* IWYU pragma: keep */}}
\DoxyCodeLine{00092 \textcolor{preprocessor}{\#include <assert.h>}}
\DoxyCodeLine{00093 \textcolor{preprocessor}{\#include <stdlib.h>}}
\DoxyCodeLine{00094 \textcolor{preprocessor}{\#include "{}librsync.h"{}}}
\DoxyCodeLine{00095 \textcolor{preprocessor}{\#include "{}job.h"{}}}
\DoxyCodeLine{00096 \textcolor{preprocessor}{\#include "{}sumset.h"{}}}
\DoxyCodeLine{00097 \textcolor{preprocessor}{\#include "{}checksum.h"{}}}
\DoxyCodeLine{00098 \textcolor{preprocessor}{\#include "{}scoop.h"{}}}
\DoxyCodeLine{00099 \textcolor{preprocessor}{\#include "{}emit.h"{}}}
\DoxyCodeLine{00100 \textcolor{preprocessor}{\#include "{}trace.h"{}}}
\DoxyCodeLine{00101 \textcolor{comment}{}}
\DoxyCodeLine{00102 \textcolor{comment}{/** Max length of a miss is 64K including 3 command bytes. */}}
\DoxyCodeLine{00103 \textcolor{preprocessor}{\#define MAX\_MISS\_LEN (MAX\_DELTA\_CMD -\/ 3)}}
\DoxyCodeLine{00104 }
\DoxyCodeLine{00105 \textcolor{keyword}{static} rs\_result rs\_delta\_s\_scan(rs\_job\_t *job);}
\DoxyCodeLine{00106 \textcolor{keyword}{static} rs\_result rs\_delta\_s\_flush(rs\_job\_t *job);}
\DoxyCodeLine{00107 \textcolor{keyword}{static} rs\_result rs\_delta\_s\_end(rs\_job\_t *job);}
\DoxyCodeLine{00108 \textcolor{keyword}{static} \textcolor{keyword}{inline} rs\_result rs\_getinput(rs\_job\_t *job, \textcolor{keywordtype}{size\_t} block\_len);}
\DoxyCodeLine{00109 \textcolor{keyword}{static} \textcolor{keyword}{inline} \textcolor{keywordtype}{int} rs\_findmatch(rs\_job\_t *job, rs\_long\_t *match\_pos,}
\DoxyCodeLine{00110                                \textcolor{keywordtype}{size\_t} *match\_len);}
\DoxyCodeLine{00111 \textcolor{keyword}{static} \textcolor{keyword}{inline} rs\_result rs\_appendmatch(rs\_job\_t *job, rs\_long\_t match\_pos,}
\DoxyCodeLine{00112                                        \textcolor{keywordtype}{size\_t} match\_len);}
\DoxyCodeLine{00113 \textcolor{keyword}{static} \textcolor{keyword}{inline} rs\_result rs\_appendmiss(rs\_job\_t *job, \textcolor{keywordtype}{size\_t} miss\_len);}
\DoxyCodeLine{00114 \textcolor{keyword}{static} \textcolor{keyword}{inline} rs\_result rs\_appendflush(rs\_job\_t *job);}
\DoxyCodeLine{00115 \textcolor{keyword}{static} \textcolor{keyword}{inline} rs\_result rs\_processmatch(rs\_job\_t *job);}
\DoxyCodeLine{00116 \textcolor{keyword}{static} \textcolor{keyword}{inline} rs\_result rs\_processmiss(rs\_job\_t *job);}
\DoxyCodeLine{00117 \textcolor{comment}{}}
\DoxyCodeLine{00118 \textcolor{comment}{/** Get a block of data if possible, and see if it matches.}}
\DoxyCodeLine{00119 \textcolor{comment}{ *}}
\DoxyCodeLine{00120 \textcolor{comment}{ * On each call, we try to process all of the input data available on the scoop}}
\DoxyCodeLine{00121 \textcolor{comment}{ * and input buffer. */}}
\DoxyCodeLine{00122 \textcolor{keyword}{static} rs\_result rs\_delta\_s\_scan(rs\_job\_t *job)}
\DoxyCodeLine{00123 \{}
\DoxyCodeLine{00124     \textcolor{keyword}{const} \textcolor{keywordtype}{size\_t} block\_len = job-\/>signature-\/>block\_len;}
\DoxyCodeLine{00125     rs\_long\_t match\_pos;}
\DoxyCodeLine{00126     \textcolor{keywordtype}{size\_t} match\_len;}
\DoxyCodeLine{00127     rs\_result result;}
\DoxyCodeLine{00128 }
\DoxyCodeLine{00129     rs\_job\_check(job);}
\DoxyCodeLine{00130     \textcolor{comment}{/* output any pending output from the tube */}}
\DoxyCodeLine{00131     \textcolor{keywordflow}{if} ((result = rs\_tube\_catchup(job)) != RS\_DONE)}
\DoxyCodeLine{00132         \textcolor{keywordflow}{return} result;}
\DoxyCodeLine{00133     \textcolor{comment}{/* read the input into the scoop */}}
\DoxyCodeLine{00134     \textcolor{keywordflow}{if} ((result = rs\_getinput(job, block\_len)) != RS\_DONE)}
\DoxyCodeLine{00135         \textcolor{keywordflow}{return} result;}
\DoxyCodeLine{00136     \textcolor{comment}{/* while output is not blocked and there is a block of data */}}
\DoxyCodeLine{00137     \textcolor{keywordflow}{while} ((result == RS\_DONE) \&\& ((job-\/>scan\_pos + block\_len) < job-\/>scan\_len)) \{}
\DoxyCodeLine{00138         \textcolor{comment}{/* check if this block matches */}}
\DoxyCodeLine{00139         \textcolor{keywordflow}{if} (rs\_findmatch(job, \&match\_pos, \&match\_len)) \{}
\DoxyCodeLine{00140             \textcolor{comment}{/* append the match and reset the weak\_sum */}}
\DoxyCodeLine{00141             result = rs\_appendmatch(job, match\_pos, match\_len);}
\DoxyCodeLine{00142             weaksum\_reset(\&job-\/>weak\_sum);}
\DoxyCodeLine{00143         \} \textcolor{keywordflow}{else} \{}
\DoxyCodeLine{00144             \textcolor{comment}{/* rotate the weak\_sum and append the miss byte */}}
\DoxyCodeLine{00145             weaksum\_rotate(\&job-\/>weak\_sum, job-\/>scan\_buf[job-\/>scan\_pos],}
\DoxyCodeLine{00146                            job-\/>scan\_buf[job-\/>scan\_pos + block\_len]);}
\DoxyCodeLine{00147             result = rs\_appendmiss(job, 1);}
\DoxyCodeLine{00148         \}}
\DoxyCodeLine{00149     \}}
\DoxyCodeLine{00150     \textcolor{comment}{/* if we completed OK */}}
\DoxyCodeLine{00151     \textcolor{keywordflow}{if} (result == RS\_DONE) \{}
\DoxyCodeLine{00152         \textcolor{comment}{/* if we reached eof, we can flush the last fragment */}}
\DoxyCodeLine{00153         \textcolor{keywordflow}{if} (job-\/>stream-\/>eof\_in) \{}
\DoxyCodeLine{00154             job-\/>statefn = rs\_delta\_s\_flush;}
\DoxyCodeLine{00155             \textcolor{keywordflow}{return} RS\_RUNNING;}
\DoxyCodeLine{00156         \} \textcolor{keywordflow}{else} \{}
\DoxyCodeLine{00157             \textcolor{comment}{/* we are blocked waiting for more data */}}
\DoxyCodeLine{00158             \textcolor{keywordflow}{return} RS\_BLOCKED;}
\DoxyCodeLine{00159         \}}
\DoxyCodeLine{00160     \}}
\DoxyCodeLine{00161     \textcolor{keywordflow}{return} result;}
\DoxyCodeLine{00162 \}}
\DoxyCodeLine{00163 }
\DoxyCodeLine{00164 \textcolor{keyword}{static} rs\_result rs\_delta\_s\_flush(rs\_job\_t *job)}
\DoxyCodeLine{00165 \{}
\DoxyCodeLine{00166     \textcolor{keyword}{const} \textcolor{keywordtype}{size\_t} block\_len = job-\/>signature-\/>block\_len;}
\DoxyCodeLine{00167     rs\_long\_t match\_pos;}
\DoxyCodeLine{00168     \textcolor{keywordtype}{size\_t} match\_len;}
\DoxyCodeLine{00169     rs\_result result;}
\DoxyCodeLine{00170 }
\DoxyCodeLine{00171     rs\_job\_check(job);}
\DoxyCodeLine{00172     \textcolor{comment}{/* output any pending output from the tube */}}
\DoxyCodeLine{00173     \textcolor{keywordflow}{if} ((result = rs\_tube\_catchup(job)) != RS\_DONE)}
\DoxyCodeLine{00174         \textcolor{keywordflow}{return} result;}
\DoxyCodeLine{00175     \textcolor{comment}{/* read the input into the scoop */}}
\DoxyCodeLine{00176     \textcolor{keywordflow}{if} ((result = rs\_getinput(job, block\_len)) != RS\_DONE)}
\DoxyCodeLine{00177         \textcolor{keywordflow}{return} result;}
\DoxyCodeLine{00178     \textcolor{comment}{/* while output is not blocked and there is any remaining data */}}
\DoxyCodeLine{00179     \textcolor{keywordflow}{while} ((result == RS\_DONE) \&\& (job-\/>scan\_pos < job-\/>scan\_len)) \{}
\DoxyCodeLine{00180         \textcolor{comment}{/* check if this block matches */}}
\DoxyCodeLine{00181         \textcolor{keywordflow}{if} (rs\_findmatch(job, \&match\_pos, \&match\_len)) \{}
\DoxyCodeLine{00182             \textcolor{comment}{/* append the match and reset the weak\_sum */}}
\DoxyCodeLine{00183             result = rs\_appendmatch(job, match\_pos, match\_len);}
\DoxyCodeLine{00184             weaksum\_reset(\&job-\/>weak\_sum);}
\DoxyCodeLine{00185         \} \textcolor{keywordflow}{else} \{}
\DoxyCodeLine{00186             \textcolor{comment}{/* rollout from weak\_sum and append the miss byte */}}
\DoxyCodeLine{00187             weaksum\_rollout(\&job-\/>weak\_sum, job-\/>scan\_buf[job-\/>scan\_pos]);}
\DoxyCodeLine{00188             rs\_trace(\textcolor{stringliteral}{"{}block reduced to "{}} FMT\_SIZE \textcolor{stringliteral}{"{}"{}},}
\DoxyCodeLine{00189                      weaksum\_count(\&job-\/>weak\_sum));}
\DoxyCodeLine{00190             result = rs\_appendmiss(job, 1);}
\DoxyCodeLine{00191         \}}
\DoxyCodeLine{00192     \}}
\DoxyCodeLine{00193     \textcolor{comment}{/* if we are not blocked, flush and set end statefn. */}}
\DoxyCodeLine{00194     \textcolor{keywordflow}{if} (result == RS\_DONE) \{}
\DoxyCodeLine{00195         result = rs\_appendflush(job);}
\DoxyCodeLine{00196         job-\/>statefn = rs\_delta\_s\_end;}
\DoxyCodeLine{00197     \}}
\DoxyCodeLine{00198     \textcolor{keywordflow}{if} (result == RS\_DONE) \{}
\DoxyCodeLine{00199         \textcolor{keywordflow}{return} RS\_RUNNING;}
\DoxyCodeLine{00200     \}}
\DoxyCodeLine{00201     \textcolor{keywordflow}{return} result;}
\DoxyCodeLine{00202 \}}
\DoxyCodeLine{00203 }
\DoxyCodeLine{00204 \textcolor{keyword}{static} rs\_result rs\_delta\_s\_end(rs\_job\_t *job)}
\DoxyCodeLine{00205 \{}
\DoxyCodeLine{00206     rs\_emit\_end\_cmd(job);}
\DoxyCodeLine{00207     \textcolor{keywordflow}{return} RS\_DONE;}
\DoxyCodeLine{00208 \}}
\DoxyCodeLine{00209 }
\DoxyCodeLine{00210 \textcolor{keyword}{static} \textcolor{keyword}{inline} rs\_result rs\_getinput(rs\_job\_t *job, \textcolor{keywordtype}{size\_t} block\_len)}
\DoxyCodeLine{00211 \{}
\DoxyCodeLine{00212     \textcolor{keywordtype}{size\_t} min\_len = block\_len + MAX\_DELTA\_CMD;}
\DoxyCodeLine{00213 }
\DoxyCodeLine{00214     job-\/>scan\_len = rs\_scoop\_avail(job);}
\DoxyCodeLine{00215     \textcolor{keywordflow}{if} (job-\/>scan\_len < min\_len \&\& !job-\/>stream-\/>eof\_in)}
\DoxyCodeLine{00216         job-\/>scan\_len = min\_len;}
\DoxyCodeLine{00217     \textcolor{keywordflow}{return} rs\_scoop\_readahead(job, job-\/>scan\_len, (\textcolor{keywordtype}{void} **)\&job-\/>scan\_buf);}
\DoxyCodeLine{00218 \}}
\DoxyCodeLine{00219 \textcolor{comment}{}}
\DoxyCodeLine{00220 \textcolor{comment}{/** find a match at scan\_pos, returning the match\_pos and match\_len.}}
\DoxyCodeLine{00221 \textcolor{comment}{ *}}
\DoxyCodeLine{00222 \textcolor{comment}{ * Note that this will calculate weak\_sum if required. It will also determine}}
\DoxyCodeLine{00223 \textcolor{comment}{ * the match\_len.}}
\DoxyCodeLine{00224 \textcolor{comment}{ *}}
\DoxyCodeLine{00225 \textcolor{comment}{ * This routine could be modified to do xdelta style matches that would extend}}
\DoxyCodeLine{00226 \textcolor{comment}{ * matches past block boundaries by matching backwards and forwards beyond the}}
\DoxyCodeLine{00227 \textcolor{comment}{ * block boundaries. Extending backwards would require decrementing scan\_pos as}}
\DoxyCodeLine{00228 \textcolor{comment}{ * appropriate. */}}
\DoxyCodeLine{00229 \textcolor{keyword}{static} \textcolor{keyword}{inline} \textcolor{keywordtype}{int} rs\_findmatch(rs\_job\_t *job, rs\_long\_t *match\_pos,}
\DoxyCodeLine{00230                                \textcolor{keywordtype}{size\_t} *match\_len)}
\DoxyCodeLine{00231 \{}
\DoxyCodeLine{00232     \textcolor{keyword}{const} \textcolor{keywordtype}{size\_t} block\_len = job-\/>signature-\/>block\_len;}
\DoxyCodeLine{00233 }
\DoxyCodeLine{00234     \textcolor{comment}{/* calculate the weak\_sum if we don't have one */}}
\DoxyCodeLine{00235     \textcolor{keywordflow}{if} (weaksum\_count(\&job-\/>weak\_sum) == 0) \{}
\DoxyCodeLine{00236         \textcolor{comment}{/* set match\_len to min(block\_len, scan\_avail) */}}
\DoxyCodeLine{00237         *match\_len = job-\/>scan\_len -\/ job-\/>scan\_pos;}
\DoxyCodeLine{00238         \textcolor{keywordflow}{if} (*match\_len > block\_len) \{}
\DoxyCodeLine{00239             *match\_len = block\_len;}
\DoxyCodeLine{00240         \}}
\DoxyCodeLine{00241         \textcolor{comment}{/* Update the weak\_sum */}}
\DoxyCodeLine{00242         weaksum\_update(\&job-\/>weak\_sum, job-\/>scan\_buf + job-\/>scan\_pos,}
\DoxyCodeLine{00243                        *match\_len);}
\DoxyCodeLine{00244         rs\_trace(\textcolor{stringliteral}{"{}calculate weak sum from scratch length "{}} FMT\_SIZE \textcolor{stringliteral}{"{}"{}},}
\DoxyCodeLine{00245                  weaksum\_count(\&job-\/>weak\_sum));}
\DoxyCodeLine{00246     \} \textcolor{keywordflow}{else} \{}
\DoxyCodeLine{00247         \textcolor{comment}{/* set the match\_len to the weak\_sum count */}}
\DoxyCodeLine{00248         *match\_len = weaksum\_count(\&job-\/>weak\_sum);}
\DoxyCodeLine{00249     \}}
\DoxyCodeLine{00250     *match\_pos =}
\DoxyCodeLine{00251         rs\_signature\_find\_match(job-\/>signature, weaksum\_digest(\&job-\/>weak\_sum),}
\DoxyCodeLine{00252                                 job-\/>scan\_buf + job-\/>scan\_pos, *match\_len);}
\DoxyCodeLine{00253     \textcolor{keywordflow}{return} *match\_pos != -\/1;}
\DoxyCodeLine{00254 \}}
\DoxyCodeLine{00255 \textcolor{comment}{}}
\DoxyCodeLine{00256 \textcolor{comment}{/** Append a match at match\_pos of length match\_len to the delta, extending a}}
\DoxyCodeLine{00257 \textcolor{comment}{ * previous match if possible, or flushing any previous miss/match. */}}
\DoxyCodeLine{00258 \textcolor{keyword}{static} \textcolor{keyword}{inline} rs\_result rs\_appendmatch(rs\_job\_t *job, rs\_long\_t match\_pos,}
\DoxyCodeLine{00259                                        \textcolor{keywordtype}{size\_t} match\_len)}
\DoxyCodeLine{00260 \{}
\DoxyCodeLine{00261     rs\_result result = RS\_DONE;}
\DoxyCodeLine{00262 }
\DoxyCodeLine{00263     \textcolor{comment}{/* if last was a match that can be extended, extend it */}}
\DoxyCodeLine{00264     \textcolor{keywordflow}{if} (job-\/>basis\_len \&\& (job-\/>basis\_pos + job-\/>basis\_len) == match\_pos) \{}
\DoxyCodeLine{00265         job-\/>basis\_len += match\_len;}
\DoxyCodeLine{00266     \} \textcolor{keywordflow}{else} \{}
\DoxyCodeLine{00267         \textcolor{comment}{/* else appendflush the last value */}}
\DoxyCodeLine{00268         result = rs\_appendflush(job);}
\DoxyCodeLine{00269         \textcolor{comment}{/* make this the new match value */}}
\DoxyCodeLine{00270         job-\/>basis\_pos = match\_pos;}
\DoxyCodeLine{00271         job-\/>basis\_len = match\_len;}
\DoxyCodeLine{00272     \}}
\DoxyCodeLine{00273     \textcolor{comment}{/* increment scan\_pos to point at next unscanned data */}}
\DoxyCodeLine{00274     job-\/>scan\_pos += match\_len;}
\DoxyCodeLine{00275     \textcolor{comment}{/* we can only process from the scoop if output is not blocked */}}
\DoxyCodeLine{00276     \textcolor{keywordflow}{if} (result == RS\_DONE) \{}
\DoxyCodeLine{00277         \textcolor{comment}{/* process the match data off the scoop */}}
\DoxyCodeLine{00278         result = rs\_processmatch(job);}
\DoxyCodeLine{00279     \}}
\DoxyCodeLine{00280     \textcolor{keywordflow}{return} result;}
\DoxyCodeLine{00281 \}}
\DoxyCodeLine{00282 \textcolor{comment}{}}
\DoxyCodeLine{00283 \textcolor{comment}{/** Append a miss of length miss\_len to the delta, extending a previous miss}}
\DoxyCodeLine{00284 \textcolor{comment}{ * if possible, or flushing any previous match.}}
\DoxyCodeLine{00285 \textcolor{comment}{ *}}
\DoxyCodeLine{00286 \textcolor{comment}{ * This also breaks misses up into 32KB segments to avoid accumulating too much}}
\DoxyCodeLine{00287 \textcolor{comment}{ * in memory. */}}
\DoxyCodeLine{00288 \textcolor{keyword}{static} \textcolor{keyword}{inline} rs\_result rs\_appendmiss(rs\_job\_t *job, \textcolor{keywordtype}{size\_t} miss\_len)}
\DoxyCodeLine{00289 \{}
\DoxyCodeLine{00290     rs\_result result = RS\_DONE;}
\DoxyCodeLine{00291 }
\DoxyCodeLine{00292     \textcolor{comment}{/* If last was a match, or MAX\_MISS\_LEN misses, appendflush it. */}}
\DoxyCodeLine{00293     \textcolor{keywordflow}{if} (job-\/>basis\_len || (job-\/>scan\_pos >= MAX\_MISS\_LEN)) \{}
\DoxyCodeLine{00294         result = rs\_appendflush(job);}
\DoxyCodeLine{00295     \}}
\DoxyCodeLine{00296     \textcolor{comment}{/* increment scan\_pos */}}
\DoxyCodeLine{00297     job-\/>scan\_pos += miss\_len;}
\DoxyCodeLine{00298     \textcolor{keywordflow}{return} result;}
\DoxyCodeLine{00299 \}}
\DoxyCodeLine{00300 \textcolor{comment}{}}
\DoxyCodeLine{00301 \textcolor{comment}{/** Flush any accumulating hit or miss, appending it to the delta. */}}
\DoxyCodeLine{00302 \textcolor{keyword}{static} \textcolor{keyword}{inline} rs\_result rs\_appendflush(rs\_job\_t *job)}
\DoxyCodeLine{00303 \{}
\DoxyCodeLine{00304     \textcolor{comment}{/* if last is a match, emit it and reset last by resetting basis\_len */}}
\DoxyCodeLine{00305     \textcolor{keywordflow}{if} (job-\/>basis\_len) \{}
\DoxyCodeLine{00306         rs\_trace(\textcolor{stringliteral}{"{}matched "{}} FMT\_LONG \textcolor{stringliteral}{"{} bytes at "{}} FMT\_LONG \textcolor{stringliteral}{"{}!"{}}, job-\/>basis\_len,}
\DoxyCodeLine{00307                  job-\/>basis\_pos);}
\DoxyCodeLine{00308         rs\_emit\_copy\_cmd(job, job-\/>basis\_pos, job-\/>basis\_len);}
\DoxyCodeLine{00309         job-\/>basis\_len = 0;}
\DoxyCodeLine{00310         \textcolor{keywordflow}{return} rs\_processmatch(job);}
\DoxyCodeLine{00311         \textcolor{comment}{/* else if last is a miss, emit and process it */}}
\DoxyCodeLine{00312     \} \textcolor{keywordflow}{else} \textcolor{keywordflow}{if} (job-\/>scan\_pos) \{}
\DoxyCodeLine{00313         rs\_trace(\textcolor{stringliteral}{"{}got "{}} FMT\_SIZE \textcolor{stringliteral}{"{} bytes of literal data"{}}, job-\/>scan\_pos);}
\DoxyCodeLine{00314         rs\_emit\_literal\_cmd(job, (\textcolor{keywordtype}{int})job-\/>scan\_pos);}
\DoxyCodeLine{00315         \textcolor{keywordflow}{return} rs\_processmiss(job);}
\DoxyCodeLine{00316     \}}
\DoxyCodeLine{00317     \textcolor{comment}{/* otherwise, nothing to flush so we are done */}}
\DoxyCodeLine{00318     \textcolor{keywordflow}{return} RS\_DONE;}
\DoxyCodeLine{00319 \}}
\DoxyCodeLine{00320 \textcolor{comment}{}}
\DoxyCodeLine{00321 \textcolor{comment}{/** Process matching data in the scoop.}}
\DoxyCodeLine{00322 \textcolor{comment}{ *}}
\DoxyCodeLine{00323 \textcolor{comment}{ * The scoop contains match data at scan\_buf of length scan\_pos. This function}}
\DoxyCodeLine{00324 \textcolor{comment}{ * processes that match data, returning RS\_DONE if it completes, or RS\_BLOCKED}}
\DoxyCodeLine{00325 \textcolor{comment}{ * if it gets blocked. After it completes scan\_pos is reset to still point at}}
\DoxyCodeLine{00326 \textcolor{comment}{ * the next unscanned data.}}
\DoxyCodeLine{00327 \textcolor{comment}{ *}}
\DoxyCodeLine{00328 \textcolor{comment}{ * This function currently just removes data from the scoop and adjusts}}
\DoxyCodeLine{00329 \textcolor{comment}{ * scan\_pos appropriately. In the future this could be used for something like}}
\DoxyCodeLine{00330 \textcolor{comment}{ * context compressing of miss data. Note that it also calls rs\_tube\_catchup to}}
\DoxyCodeLine{00331 \textcolor{comment}{ * output any pending output. */}}
\DoxyCodeLine{00332 \textcolor{keyword}{static} \textcolor{keyword}{inline} rs\_result rs\_processmatch(rs\_job\_t *job)}
\DoxyCodeLine{00333 \{}
\DoxyCodeLine{00334     assert(job-\/>copy\_len == 0);}
\DoxyCodeLine{00335     rs\_scoop\_advance(job, job-\/>scan\_pos);}
\DoxyCodeLine{00336     job-\/>scan\_buf += job-\/>scan\_pos;}
\DoxyCodeLine{00337     job-\/>scan\_len -\/= job-\/>scan\_pos;}
\DoxyCodeLine{00338     job-\/>scan\_pos = 0;}
\DoxyCodeLine{00339     \textcolor{keywordflow}{return} rs\_tube\_catchup(job);}
\DoxyCodeLine{00340 \}}
\DoxyCodeLine{00341 \textcolor{comment}{}}
\DoxyCodeLine{00342 \textcolor{comment}{/** Process miss data in the scoop.}}
\DoxyCodeLine{00343 \textcolor{comment}{ *}}
\DoxyCodeLine{00344 \textcolor{comment}{ * The scoop contains miss data at scan\_buf of length scan\_pos. This function}}
\DoxyCodeLine{00345 \textcolor{comment}{ * processes that miss data, returning RS\_DONE if it completes, or RS\_BLOCKED}}
\DoxyCodeLine{00346 \textcolor{comment}{ * if it gets blocked. After it completes scan\_pos is reset to still point at}}
\DoxyCodeLine{00347 \textcolor{comment}{ * the next unscanned data.}}
\DoxyCodeLine{00348 \textcolor{comment}{ *}}
\DoxyCodeLine{00349 \textcolor{comment}{ * This function uses rs\_tube\_copy to queue copying from the scoop into output.}}
\DoxyCodeLine{00350 \textcolor{comment}{ * and uses rs\_tube\_catchup to do the copying. This automaticly removes data}}
\DoxyCodeLine{00351 \textcolor{comment}{ * from the scoop, but this can block. While rs\_tube\_catchup is blocked,}}
\DoxyCodeLine{00352 \textcolor{comment}{ * scan\_pos does not point at legit data, so scanning can also not proceed.}}
\DoxyCodeLine{00353 \textcolor{comment}{ *}}
\DoxyCodeLine{00354 \textcolor{comment}{ * In the future this could do compression of miss data before outputing it. */}}
\DoxyCodeLine{00355 \textcolor{keyword}{static} \textcolor{keyword}{inline} rs\_result rs\_processmiss(rs\_job\_t *job)}
\DoxyCodeLine{00356 \{}
\DoxyCodeLine{00357     assert(job-\/>write\_len > 0);}
\DoxyCodeLine{00358     rs\_tube\_copy(job, job-\/>scan\_pos);}
\DoxyCodeLine{00359     job-\/>scan\_buf += job-\/>scan\_pos;}
\DoxyCodeLine{00360     job-\/>scan\_len -\/= job-\/>scan\_pos;}
\DoxyCodeLine{00361     job-\/>scan\_pos = 0;}
\DoxyCodeLine{00362     \textcolor{keywordflow}{return} rs\_tube\_catchup(job);}
\DoxyCodeLine{00363 \}}
\DoxyCodeLine{00364 \textcolor{comment}{}}
\DoxyCodeLine{00365 \textcolor{comment}{/** State function that does a slack delta containing only literal data to}}
\DoxyCodeLine{00366 \textcolor{comment}{ * recreate the input. */}}
\DoxyCodeLine{00367 \textcolor{keyword}{static} rs\_result rs\_delta\_s\_slack(rs\_job\_t *job)}
\DoxyCodeLine{00368 \{}
\DoxyCodeLine{00369     \textcolor{keywordtype}{size\_t} avail = rs\_scoop\_avail(job);}
\DoxyCodeLine{00370 }
\DoxyCodeLine{00371     \textcolor{keywordflow}{if} (avail) \{}
\DoxyCodeLine{00372         rs\_trace(\textcolor{stringliteral}{"{}emit slack delta for "{}} FMT\_SIZE \textcolor{stringliteral}{"{} available bytes"{}}, avail);}
\DoxyCodeLine{00373         rs\_emit\_literal\_cmd(job, (\textcolor{keywordtype}{int})avail);}
\DoxyCodeLine{00374         rs\_tube\_copy(job, avail);}
\DoxyCodeLine{00375         \textcolor{keywordflow}{return} RS\_RUNNING;}
\DoxyCodeLine{00376     \} \textcolor{keywordflow}{else} \textcolor{keywordflow}{if} (rs\_scoop\_eof(job)) \{}
\DoxyCodeLine{00377         job-\/>statefn = rs\_delta\_s\_end;}
\DoxyCodeLine{00378         \textcolor{keywordflow}{return} RS\_RUNNING;}
\DoxyCodeLine{00379     \}}
\DoxyCodeLine{00380     \textcolor{keywordflow}{return} RS\_BLOCKED;}
\DoxyCodeLine{00381 \}}
\DoxyCodeLine{00382 \textcolor{comment}{}}
\DoxyCodeLine{00383 \textcolor{comment}{/** State function for writing out the header of the encoding job. */}}
\DoxyCodeLine{00384 \textcolor{keyword}{static} rs\_result rs\_delta\_s\_header(rs\_job\_t *job)}
\DoxyCodeLine{00385 \{}
\DoxyCodeLine{00386     rs\_emit\_delta\_header(job);}
\DoxyCodeLine{00387     \textcolor{keywordflow}{if} (job-\/>signature) \{}
\DoxyCodeLine{00388         job-\/>statefn = rs\_delta\_s\_scan;}
\DoxyCodeLine{00389     \} \textcolor{keywordflow}{else} \{}
\DoxyCodeLine{00390         rs\_trace(\textcolor{stringliteral}{"{}no signature provided for delta, using slack deltas"{}});}
\DoxyCodeLine{00391         job-\/>statefn = rs\_delta\_s\_slack;}
\DoxyCodeLine{00392     \}}
\DoxyCodeLine{00393     \textcolor{keywordflow}{return} RS\_RUNNING;}
\DoxyCodeLine{00394 \}}
\DoxyCodeLine{00395 }
\DoxyCodeLine{00396 rs\_job\_t *rs\_delta\_begin(rs\_signature\_t *sig)}
\DoxyCodeLine{00397 \{}
\DoxyCodeLine{00398     rs\_job\_t *job;}
\DoxyCodeLine{00399 }
\DoxyCodeLine{00400     job = rs\_job\_new(\textcolor{stringliteral}{"{}delta"{}}, rs\_delta\_s\_header);}
\DoxyCodeLine{00401     \textcolor{comment}{/* Caller can pass NULL sig or empty sig for "{}slack deltas"{}. */}}
\DoxyCodeLine{00402     \textcolor{keywordflow}{if} (sig \&\& sig-\/>count > 0) \{}
\DoxyCodeLine{00403         rs\_signature\_check(sig);}
\DoxyCodeLine{00404         \textcolor{comment}{/* Caller must have called rs\_build\_hash\_table() by now. */}}
\DoxyCodeLine{00405         assert(sig-\/>hashtable);}
\DoxyCodeLine{00406         job-\/>signature = sig;}
\DoxyCodeLine{00407         weaksum\_init(\&job-\/>weak\_sum, rs\_signature\_weaksum\_kind(sig));}
\DoxyCodeLine{00408     \}}
\DoxyCodeLine{00409     \textcolor{keywordflow}{return} job;}
\DoxyCodeLine{00410 \}}

\end{DoxyCode}
