$treeview $search $mathjax $extrastylesheet
librsync
2.3.1
$projectbrief
|
$projectbrief
|
$searchbox |
00001 /*= -*- c-basic-offset: 4; indent-tabs-mode: nil; -*- 00002 * 00003 * librsync -- the library for network deltas 00004 * 00005 * Copyright (C) 2000, 2001 by Martin Pool <mbp@sourcefrog.net> 00006 * 00007 * This program is free software; you can redistribute it and/or modify 00008 * it under the terms of the GNU Lesser General Public License as published by 00009 * the Free Software Foundation; either version 2.1 of the License, or 00010 * (at your option) any later version. 00011 * 00012 * This program is distributed in the hope that it will be useful, 00013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00015 * GNU Lesser General Public License for more details. 00016 * 00017 * You should have received a copy of the GNU Lesser General Public License 00018 * along with this program; if not, write to the Free Software 00019 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 00020 */ 00021 #ifndef _CHECKSUM_H_ 00022 # define _CHECKSUM_H_ 00023 # include <assert.h> 00024 # include "librsync.h" 00025 # include "rollsum.h" 00026 # include "rabinkarp.h" 00027 # include "hashtable.h" 00028 00029 /** Weaksum implementations. */ 00030 typedef enum { 00031 RS_ROLLSUM, 00032 RS_RABINKARP, 00033 } weaksum_kind_t; 00034 00035 /** Strongsum implementations. */ 00036 typedef enum { 00037 RS_MD4, 00038 RS_BLAKE2, 00039 } strongsum_kind_t; 00040 00041 /** Abstract wrapper around weaksum implementations. 00042 * 00043 * This is a polymorphic interface to the different rollsum implementations. 00044 * 00045 * Historically rollsum methods were implemented as static inline functions 00046 * because they were small and needed to be fast. Now that we need to call 00047 * different methods for different rollsum implementations, they are getting 00048 * more complicated. Is it better to delegate calls to the right implementation 00049 * using static inline switch statements, or stop inlining them and use virtual 00050 * method pointers? Tests suggest inlined switch statements is faster. */ 00051 typedef struct weaksum { 00052 weaksum_kind_t kind; 00053 union { 00054 Rollsum rs; 00055 rabinkarp_t rk; 00056 } sum; 00057 } weaksum_t; 00058 00059 static inline void weaksum_reset(weaksum_t *sum) 00060 { 00061 if (sum->kind == RS_ROLLSUM) 00062 RollsumInit(&sum->sum.rs); 00063 else 00064 rabinkarp_init(&sum->sum.rk); 00065 } 00066 00067 static inline void weaksum_init(weaksum_t *sum, weaksum_kind_t kind) 00068 { 00069 assert(kind == RS_ROLLSUM || kind == RS_RABINKARP); 00070 sum->kind = kind; 00071 weaksum_reset(sum); 00072 } 00073 00074 static inline size_t weaksum_count(weaksum_t *sum) 00075 { 00076 /* We take advantage of sum->sum.rs.count overlaying sum->sum.rk.count. */ 00077 return sum->sum.rs.count; 00078 } 00079 00080 static inline void weaksum_update(weaksum_t *sum, const unsigned char *buf, 00081 size_t len) 00082 { 00083 if (sum->kind == RS_ROLLSUM) 00084 RollsumUpdate(&sum->sum.rs, buf, len); 00085 else 00086 rabinkarp_update(&sum->sum.rk, buf, len); 00087 } 00088 00089 static inline void weaksum_rotate(weaksum_t *sum, unsigned char out, 00090 unsigned char in) 00091 { 00092 if (sum->kind == RS_ROLLSUM) 00093 RollsumRotate(&sum->sum.rs, out, in); 00094 else 00095 rabinkarp_rotate(&sum->sum.rk, out, in); 00096 } 00097 00098 static inline void weaksum_rollin(weaksum_t *sum, unsigned char in) 00099 { 00100 if (sum->kind == RS_ROLLSUM) 00101 RollsumRollin(&sum->sum.rs, in); 00102 else 00103 rabinkarp_rollin(&sum->sum.rk, in); 00104 } 00105 00106 static inline void weaksum_rollout(weaksum_t *sum, unsigned char out) 00107 { 00108 if (sum->kind == RS_ROLLSUM) 00109 RollsumRollout(&sum->sum.rs, out); 00110 else 00111 rabinkarp_rollout(&sum->sum.rk, out); 00112 } 00113 00114 static inline rs_weak_sum_t weaksum_digest(weaksum_t *sum) 00115 { 00116 if (sum->kind == RS_ROLLSUM) 00117 /* We apply mix32() to rollsums before using them for matching. */ 00118 return mix32(RollsumDigest(&sum->sum.rs)); 00119 else 00120 return rabinkarp_digest(&sum->sum.rk); 00121 } 00122 00123 /** Calculate a weaksum. 00124 * 00125 * Note this does not apply mix32() to rollsum digests, unlike 00126 * weaksum_digest(). This is because rollsums are stored raw without mix32() 00127 * applied for backwards-compatibility, but we apply mix32() when adding them 00128 * into a signature and when getting the digest for calculating deltas. */ 00129 rs_weak_sum_t rs_calc_weak_sum(weaksum_kind_t kind, void const *buf, 00130 size_t len); 00131 00132 /** Calculate a strongsum. */ 00133 void rs_calc_strong_sum(strongsum_kind_t kind, void const *buf, size_t len, 00134 rs_strong_sum_t *sum); 00135 00136 #endif /* _CHECKSUM_H_ */