OLD | NEW |
---|---|
1 // Copyright 2003, 2004 Colin Percival | 1 // Copyright 2003, 2004 Colin Percival |
2 // All rights reserved | 2 // All rights reserved |
3 // | 3 // |
4 // Redistribution and use in source and binary forms, with or without | 4 // Redistribution and use in source and binary forms, with or without |
5 // modification, are permitted providing that the following conditions | 5 // modification, are permitted providing that the following conditions |
6 // are met: | 6 // are met: |
7 // 1. Redistributions of source code must retain the above copyright | 7 // 1. Redistributions of source code must retain the above copyright |
8 // notice, this list of conditions and the following disclaimer. | 8 // notice, this list of conditions and the following disclaimer. |
9 // 2. Redistributions in binary form must reproduce the above copyright | 9 // 2. Redistributions in binary form must reproduce the above copyright |
10 // notice, this list of conditions and the following disclaimer in the | 10 // notice, this list of conditions and the following disclaimer in the |
(...skipping 20 matching lines...) Expand all Loading... | |
31 // --Benjamin Smedberg <benjamin@smedbergs.us> | 31 // --Benjamin Smedberg <benjamin@smedbergs.us> |
32 // 2005-05-18 - Use the same CRC algorithm as bzip2, and leverage the CRC table | 32 // 2005-05-18 - Use the same CRC algorithm as bzip2, and leverage the CRC table |
33 // provided by libbz2. | 33 // provided by libbz2. |
34 // --Darin Fisher <darin@meer.net> | 34 // --Darin Fisher <darin@meer.net> |
35 // 2007-11-14 - Changed to use Crc from Lzma library instead of Bzip library | 35 // 2007-11-14 - Changed to use Crc from Lzma library instead of Bzip library |
36 // --Rahul Kuchhal | 36 // --Rahul Kuchhal |
37 // 2009-03-31 - Change to use Streams. Added lots of comments. | 37 // 2009-03-31 - Change to use Streams. Added lots of comments. |
38 // --Stephen Adams <sra@chromium.org> | 38 // --Stephen Adams <sra@chromium.org> |
39 // 2010-05-26 - Use a paged array for V and I. The address space may be too | 39 // 2010-05-26 - Use a paged array for V and I. The address space may be too |
40 // fragmented for these big arrays to be contiguous. | 40 // fragmented for these big arrays to be contiguous. |
41 // --Stephen Adams <sra@chromium.org> | 41 // --Stephen Adams <sra@chromium.org> |
chrisha
2016/08/02 15:26:00
Fix indent while you're here?
huangs
2016/08/02 18:32:53
Done.
| |
42 // 2015-08-03 - Extract qsufsort portion to a separate file. | 42 // 2015-08-03 - Extract qsufsort portion to a separate file. |
43 // --Samuel Huang <huangs@chromium.org> | 43 // --Samuel Huang <huangs@chromium.org> |
44 // 2015-08-12 - Interface change to search(). | 44 // 2015-08-12 - Interface change to search(). |
45 // --Samuel Huang <huangs@chromium.org> | 45 // --Samuel Huang <huangs@chromium.org> |
46 // 2016-07-29 - Replacing qsufsort with divsufsort. | |
47 // --Samuel Huang <huangs@chromium.org> | |
46 | 48 |
47 // Copyright 2016 The Chromium Authors. All rights reserved. | 49 // Copyright 2016 The Chromium Authors. All rights reserved. |
48 // Use of this source code is governed by a BSD-style license that can be | 50 // Use of this source code is governed by a BSD-style license that can be |
49 // found in the LICENSE file. | 51 // found in the LICENSE file. |
50 | 52 |
51 #include "courgette/third_party/bsdiff/bsdiff.h" | 53 #include "courgette/third_party/bsdiff/bsdiff.h" |
52 | 54 |
53 #include <stddef.h> | 55 #include <stddef.h> |
54 #include <stdint.h> | 56 #include <stdint.h> |
55 #include <stdlib.h> | 57 #include <stdlib.h> |
58 | |
56 #include <algorithm> | 59 #include <algorithm> |
57 | 60 |
58 #include "base/logging.h" | 61 #include "base/logging.h" |
59 #include "base/strings/string_util.h" | 62 #include "base/strings/string_util.h" |
60 #include "base/time/time.h" | 63 #include "base/time/time.h" |
61 | 64 |
62 #include "courgette/crc.h" | 65 #include "courgette/crc.h" |
63 #include "courgette/streams.h" | 66 #include "courgette/streams.h" |
64 #include "courgette/third_party/bsdiff/bsdiff_search.h" | 67 #include "courgette/third_party/bsdiff/bsdiff_search.h" |
65 #include "courgette/third_party/bsdiff/paged_array.h" | 68 #include "courgette/third_party/bsdiff/paged_array.h" |
66 #include "courgette/third_party/bsdiff/qsufsort.h" | 69 #include "courgette/third_party/divsufsort/divsufsort.h" |
67 | 70 |
68 namespace { | 71 namespace { |
69 | 72 |
70 using courgette::CalculateCrc; | 73 using courgette::CalculateCrc; |
71 using courgette::PagedArray; | 74 using courgette::PagedArray; |
72 using courgette::SinkStream; | 75 using courgette::SinkStream; |
73 using courgette::SinkStreamSet; | 76 using courgette::SinkStreamSet; |
74 using courgette::SourceStream; | 77 using courgette::SourceStream; |
75 using courgette::SourceStreamSet; | 78 using courgette::SourceStreamSet; |
76 | 79 |
(...skipping 22 matching lines...) Expand all Loading... | |
99 SinkStream* control_stream_seeks = patch_streams.stream(2); | 102 SinkStream* control_stream_seeks = patch_streams.stream(2); |
100 SinkStream* diff_skips = patch_streams.stream(3); | 103 SinkStream* diff_skips = patch_streams.stream(3); |
101 SinkStream* diff_bytes = patch_streams.stream(4); | 104 SinkStream* diff_bytes = patch_streams.stream(4); |
102 SinkStream* extra_bytes = patch_streams.stream(5); | 105 SinkStream* extra_bytes = patch_streams.stream(5); |
103 | 106 |
104 const uint8_t* old = old_stream->Buffer(); | 107 const uint8_t* old = old_stream->Buffer(); |
105 const int oldsize = static_cast<int>(old_stream->Remaining()); | 108 const int oldsize = static_cast<int>(old_stream->Remaining()); |
106 | 109 |
107 uint32_t pending_diff_zeros = 0; | 110 uint32_t pending_diff_zeros = 0; |
108 | 111 |
109 PagedArray<int> I; | 112 PagedArray<divsuf::saidx_t> I; |
110 PagedArray<int> V; | |
111 | 113 |
112 if (!I.Allocate(oldsize + 1)) { | 114 if (!I.Allocate(oldsize + 1)) { |
113 LOG(ERROR) << "Could not allocate I[], " << ((oldsize + 1) * sizeof(int)) | 115 LOG(ERROR) << "Could not allocate I[], " << ((oldsize + 1) * sizeof(int)) |
114 << " bytes"; | 116 << " bytes"; |
115 return MEM_ERROR; | 117 return MEM_ERROR; |
116 } | 118 } |
117 | 119 |
118 if (!V.Allocate(oldsize + 1)) { | |
119 LOG(ERROR) << "Could not allocate V[], " << ((oldsize + 1) * sizeof(int)) | |
120 << " bytes"; | |
121 return MEM_ERROR; | |
122 } | |
123 | |
124 base::Time q_start_time = base::Time::Now(); | 120 base::Time q_start_time = base::Time::Now(); |
125 qsuf::qsufsort<PagedArray<int>&>(I, V, old, oldsize); | 121 divsuf::saint_t result = divsuf::divsufsort_include_empty( |
126 VLOG(1) << " done qsufsort " | 122 old, I.begin(), oldsize); |
123 VLOG(1) << " done divsufsort " | |
127 << (base::Time::Now() - q_start_time).InSecondsF(); | 124 << (base::Time::Now() - q_start_time).InSecondsF(); |
128 V.clear(); | 125 if (result != 0) |
126 return UNEXPECTED_ERROR; | |
129 | 127 |
130 const uint8_t* newbuf = new_stream->Buffer(); | 128 const uint8_t* newbuf = new_stream->Buffer(); |
131 const int newsize = static_cast<int>(new_stream->Remaining()); | 129 const int newsize = static_cast<int>(new_stream->Remaining()); |
132 | 130 |
133 int control_length = 0; | 131 int control_length = 0; |
134 int diff_bytes_length = 0; | 132 int diff_bytes_length = 0; |
135 int diff_bytes_nonzero = 0; | 133 int diff_bytes_nonzero = 0; |
136 int extra_bytes_length = 0; | 134 int extra_bytes_length = 0; |
137 | 135 |
138 // The patch format is a sequence of triples <copy,extra,seek> where 'copy' is | 136 // The patch format is a sequence of triples <copy,extra,seek> where 'copy' is |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
178 int scan = 0; | 176 int scan = 0; |
179 SearchResult match(0, 0); | 177 SearchResult match(0, 0); |
180 | 178 |
181 while (scan < newsize) { | 179 while (scan < newsize) { |
182 int oldscore = 0; // Count of how many bytes of the current match at |scan| | 180 int oldscore = 0; // Count of how many bytes of the current match at |scan| |
183 // extend the match at |lastscan|. | 181 // extend the match at |lastscan|. |
184 match.pos = 0; | 182 match.pos = 0; |
185 | 183 |
186 scan += match.size; | 184 scan += match.size; |
187 for (int scsc = scan; scan < newsize; ++scan) { | 185 for (int scsc = scan; scan < newsize; ++scan) { |
188 match = search<PagedArray<int>&>( | 186 match = search<PagedArray<divsuf::saidx_t>&>( |
189 I, old, oldsize, newbuf + scan, newsize - scan); | 187 I, old, oldsize, newbuf + scan, newsize - scan); |
190 | 188 |
191 for (; scsc < scan + match.size; scsc++) | 189 for (; scsc < scan + match.size; scsc++) |
192 if ((scsc + lastoffset < oldsize) && | 190 if ((scsc + lastoffset < oldsize) && |
193 (old[scsc + lastoffset] == newbuf[scsc])) | 191 (old[scsc + lastoffset] == newbuf[scsc])) |
194 oldscore++; | 192 oldscore++; |
195 | 193 |
196 if ((match.size == oldscore) && (match.size != 0)) | 194 if ((match.size == oldscore) && (match.size != 0)) |
197 break; // Good continuing match, case (1) | 195 break; // Good continuing match, case (1) |
198 if (match.size > oldscore + 8) | 196 if (match.size > oldscore + 8) |
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
344 << " extra bytes: " << extra_bytes_length | 342 << " extra bytes: " << extra_bytes_length |
345 << "\nUncompressed bsdiff patch size " | 343 << "\nUncompressed bsdiff patch size " |
346 << patch_stream->Length() - initial_patch_stream_length | 344 << patch_stream->Length() - initial_patch_stream_length |
347 << "\nEnd bsdiff " | 345 << "\nEnd bsdiff " |
348 << (base::Time::Now() - start_bsdiff_time).InSecondsF(); | 346 << (base::Time::Now() - start_bsdiff_time).InSecondsF(); |
349 | 347 |
350 return OK; | 348 return OK; |
351 } | 349 } |
352 | 350 |
353 } // namespace bsdiff | 351 } // namespace bsdiff |
OLD | NEW |