Ticket #348: compressed-changesets.diff
File compressed-changesets.diff, 26.2 KB (added by , 13 years ago) |
---|
-
bootstrap
diff --git a/bootstrap b/bootstrap index 7998897..7376fd6 100755
a b else 236 236 AUTOCONF=$instdir/bin/autoconf \ 237 237 lazy_build automake 1.11.2 tar.bz2 34b3808e1d536ee3724fbde28bc1f13b8b40dc43 238 238 lazy_build libtool 2.4.2 tar.gz 22b71a8b5ce3ad86e1094e7285981cae10e6ff88 239 if [ "$1" = "--deps=libmagic" ] ; then 240 shift 241 lazy_build file 5.10 tar.gz 72fd435e78955ee122b7b3d323ff2f92e6263e89 242 fi 239 243 240 244 for v in $autotools ; do 241 245 tool=`echo "$v"|tr A-Z a-z` … … for d in $modules ; do 414 418 xapian-core) 415 419 cd "$d" && "$configure" --enable-maintainer-mode --cache-file="$here/config.cache" ${1+"$@"} 416 420 ;; 421 xapian-applications/omega) 422 cd "$d" && "$configure" --enable-maintainer-mode XAPIAN_CONFIG="$XAPIAN_CONFIG" CXXFLAGS="-I$srcdir/INST/include -L$srcdir/INST/lib" ${1+"$@"} 423 ;; 417 424 *) 418 425 cd "$d" && "$configure" --enable-maintainer-mode --cache-file="$here/config.cache" XAPIAN_CONFIG="$XAPIAN_CONFIG" ${1+"$@"} 419 426 ;; -
xapian-core/backends/brass/brass_database.cc
diff --git a/xapian-core/backends/brass/brass_database.cc b/xapian-core/backends/brass/brass_database.cc index 3ad7197..28335ea 100644
a b BrassDatabase::set_revision_number(brass_revision_number_t new_revision) 444 444 // table last, so that ends up cached the most, if the cache 445 445 // available is limited. Do the position table just before that 446 446 // as having that cached will also improve search performance. 447 termlist_table.write_changed_blocks(changes_fd); 448 synonym_table.write_changed_blocks(changes_fd); 449 spelling_table.write_changed_blocks(changes_fd); 450 record_table.write_changed_blocks(changes_fd); 451 position_table.write_changed_blocks(changes_fd); 452 postlist_table.write_changed_blocks(changes_fd); 447 bool compressed = CHANGES_VERSION != 1; 448 449 //FIXME:dc: this is the wrong place to define the compression 450 termlist_table.write_changed_blocks(changes_fd, compressed); 451 synonym_table.write_changed_blocks(changes_fd, compressed); 452 spelling_table.write_changed_blocks(changes_fd, compressed); 453 record_table.write_changed_blocks(changes_fd, compressed); 454 position_table.write_changed_blocks(changes_fd, compressed); 455 postlist_table.write_changed_blocks(changes_fd, compressed); 453 456 } 454 457 455 458 postlist_table.commit(new_revision, changes_fd); -
xapian-core/backends/brass/brass_databasereplicator.cc
diff --git a/xapian-core/backends/brass/brass_databasereplicator.cc b/xapian-core/backends/brass/brass_databasereplicator.cc index 002df61..a8b1875 100644
a b 20 20 * USA 21 21 */ 22 22 23 #include <iostream> 23 24 #include <config.h> 24 25 25 26 #include "brass_databasereplicator.h" … … 34 35 #include "debuglog.h" 35 36 #include "fd.h" 36 37 #include "filetests.h" 38 #include "internaltypes.h" 37 39 #include "io_utils.h" 38 40 #include "pack.h" 39 41 #include "net/remoteconnection.h" … … 42 44 #include "str.h" 43 45 #include "stringutils.h" 44 46 47 45 48 #ifdef __WIN32__ 46 49 # include "msvc_posix_wrapper.h" 47 50 #endif … … using namespace std; 52 55 using namespace Xapian; 53 56 54 57 BrassDatabaseReplicator::BrassDatabaseReplicator(const string & db_dir_) 55 : db_dir(db_dir_) 58 : db_dir(db_dir_), 59 comp_stream(Z_DEFAULT_STRATEGY) 56 60 { 57 61 } 58 62 … … BrassDatabaseReplicator::process_changeset_chunk_blocks(const string & tablename 191 195 } 192 196 { 193 197 FD closer(fd); 194 198 Bytef out[8192]; 195 199 while (true) { 196 200 conn.get_message_chunk(buf, REASONABLE_CHANGESET_SIZE, end_time); 197 201 ptr = buf.data(); 198 202 end = ptr + buf.size(); 199 200 203 uint4 block_number; 201 204 if (!unpack_uint(&ptr, end, &block_number)) 202 205 throw NetworkError("Invalid block number in changeset"); … … BrassDatabaseReplicator::process_changeset_chunk_blocks(const string & tablename 205 208 break; 206 209 --block_number; 207 210 208 conn.get_message_chunk(buf, changeset_blocksize, end_time); 211 conn.get_message_chunk(buf, REASONABLE_CHANGESET_SIZE, end_time); 212 ptr = buf.data(); 213 end = ptr + buf.size(); 214 unsigned int compressed_block_size; 215 if(!unpack_uint(&ptr, end, &compressed_block_size)) 216 throw NetworkError("Invalid v2 cphangeset"); 217 buf.erase(0, ptr - buf.data()); 218 219 if (compressed_block_size > 0) { 220 string ubuf; 221 ubuf.reserve(changeset_blocksize); 222 conn.get_message_chunk(buf, changeset_blocksize, end_time); 223 comp_stream.lazy_alloc_inflate_zstream(); 224 comp_stream.inflate_zstream->next_in = (Bytef*)const_cast<char *>(buf.data()); 225 comp_stream.inflate_zstream->avail_in = (uInt)(buf.size()); 226 comp_stream.inflate_zstream->next_out = out; 227 comp_stream.inflate_zstream->avail_out = (uInt)sizeof(out); 228 int err = inflate(comp_stream.inflate_zstream, Z_FINISH); 229 if (err == Z_STREAM_END) { 230 std::cout << comp_stream.inflate_zstream->next_out - out << std::endl; 231 std::cout << out << std::endl; 232 ubuf.append(reinterpret_cast<const char *>(out), 233 comp_stream.inflate_zstream->next_out - out); 234 swap(buf, ubuf); 235 } 236 } else { 237 conn.get_message_chunk(buf, changeset_blocksize, end_time); 238 } 209 239 if (buf.size() < changeset_blocksize) 210 240 throw NetworkError("Incomplete block in changeset"); 211 241 … … BrassDatabaseReplicator::apply_changeset_from_conn(RemoteConnection & conn, 255 285 buf.erase(0, 12); 256 286 const char *ptr = buf.data(); 257 287 const char *end = ptr + buf.size(); 258 259 288 unsigned int changes_version; 260 289 if (!unpack_uint(&ptr, end, &changes_version)) 261 290 throw NetworkError("Couldn't read a valid version number from changeset"); -
xapian-core/backends/brass/brass_databasereplicator.h
diff --git a/xapian-core/backends/brass/brass_databasereplicator.h b/xapian-core/backends/brass/brass_databasereplicator.h index 3176589..915fb1f 100644
a b 24 24 #define XAPIAN_INCLUDED_BRASS_DATABASEREPLICATOR_H 25 25 26 26 #include "backends/databasereplicator.h" 27 #include "zlib_utils.h" 27 28 28 29 class BrassDatabaseReplicator : public Xapian::DatabaseReplicator { 29 30 private: … … class BrassDatabaseReplicator : public Xapian::DatabaseReplicator { 31 32 */ 32 33 std::string db_dir; 33 34 35 CompressionStream comp_stream; 36 34 37 /** Process a chunk which holds a base block. 35 38 */ 36 39 void process_changeset_chunk_base(const std::string & tablename, -
xapian-core/backends/brass/brass_replicate_internal.h
diff --git a/xapian-core/backends/brass/brass_replicate_internal.h b/xapian-core/backends/brass/brass_replicate_internal.h index d108710..24d140d 100644
a b 28 28 29 29 // The current version of changeset files. 30 30 // 1 - initial implementation 31 #define CHANGES_VERSION 1u 31 // 2 - compressed changesets 32 #define CHANGES_VERSION 2u 32 33 33 34 // Must be big enough to ensure that the start of the changeset (up to the new 34 35 // revision number) will fit in this much space. -
xapian-core/backends/brass/brass_table.cc
diff --git a/xapian-core/backends/brass/brass_table.cc b/xapian-core/backends/brass/brass_table.cc index d8ddc74..e77312b 100644
a b BrassTable::add(const string &key, string tag, bool already_compressed) 1030 1030 CompileTimeAssert(DONT_COMPRESS != Z_RLE); 1031 1031 #endif 1032 1032 1033 lazy_alloc_deflate_zstream();1033 comp_stream.lazy_alloc_deflate_zstream(); 1034 1034 1035 deflate_zstream->next_in = (Bytef *)const_cast<char *>(tag.data());1036 deflate_zstream->avail_in = (uInt)tag.size();1035 comp_stream.deflate_zstream->next_in = (Bytef *)const_cast<char *>(tag.data()); 1036 comp_stream.deflate_zstream->avail_in = (uInt)tag.size(); 1037 1037 1038 1038 // If compressed size is >= tag.size(), we don't want to compress. 1039 1039 unsigned long blk_len = tag.size() - 1; 1040 1040 unsigned char * blk = new unsigned char[blk_len]; 1041 deflate_zstream->next_out = blk;1042 deflate_zstream->avail_out = (uInt)blk_len;1041 comp_stream.deflate_zstream->next_out = blk; 1042 comp_stream.deflate_zstream->avail_out = (uInt)blk_len; 1043 1043 1044 int err = deflate( deflate_zstream, Z_FINISH);1044 int err = deflate(comp_stream.deflate_zstream, Z_FINISH); 1045 1045 if (err == Z_STREAM_END) { 1046 1046 // If deflate succeeded, then the output was at least one byte 1047 1047 // smaller than the input. 1048 tag.assign(reinterpret_cast<const char *>(blk), deflate_zstream->total_out);1048 tag.assign(reinterpret_cast<const char *>(blk), comp_stream.deflate_zstream->total_out); 1049 1049 compressed = true; 1050 1050 } else { 1051 1051 // Deflate failed - presumably the data wasn't compressible. … … BrassTable::read_tag(Brass::Cursor * C_, string *tag, bool keep_compressed) cons 1240 1240 1241 1241 Bytef buf[8192]; 1242 1242 1243 lazy_alloc_inflate_zstream();1243 comp_stream.lazy_alloc_inflate_zstream(); 1244 1244 1245 inflate_zstream->next_in = (Bytef*)const_cast<char *>(tag->data());1246 inflate_zstream->avail_in = (uInt)tag->size();1245 comp_stream.inflate_zstream->next_in = (Bytef*)const_cast<char *>(tag->data()); 1246 comp_stream.inflate_zstream->avail_in = (uInt)tag->size(); 1247 1247 1248 1248 int err = Z_OK; 1249 1249 while (err != Z_STREAM_END) { 1250 inflate_zstream->next_out = buf;1251 inflate_zstream->avail_out = (uInt)sizeof(buf);1252 err = inflate( inflate_zstream, Z_SYNC_FLUSH);1253 if (err == Z_BUF_ERROR && inflate_zstream->avail_in == 0) {1254 LOGLINE(DB, "Z_BUF_ERROR - faking checksum of " << inflate_zstream->adler);1250 comp_stream.inflate_zstream->next_out = buf; 1251 comp_stream.inflate_zstream->avail_out = (uInt)sizeof(buf); 1252 err = inflate(comp_stream.inflate_zstream, Z_SYNC_FLUSH); 1253 if (err == Z_BUF_ERROR && comp_stream.inflate_zstream->avail_in == 0) { 1254 LOGLINE(DB, "Z_BUF_ERROR - faking checksum of " << comp_stream.inflate_zstream->adler); 1255 1255 Bytef header2[4]; 1256 setint4(header2, 0, inflate_zstream->adler);1257 inflate_zstream->next_in = header2;1258 inflate_zstream->avail_in = 4;1259 err = inflate( inflate_zstream, Z_SYNC_FLUSH);1256 setint4(header2, 0, comp_stream.inflate_zstream->adler); 1257 comp_stream.inflate_zstream->next_in = header2; 1258 comp_stream.inflate_zstream->avail_in = 4; 1259 err = inflate(comp_stream.inflate_zstream, Z_SYNC_FLUSH); 1260 1260 if (err == Z_STREAM_END) break; 1261 1261 } 1262 1262 1263 1263 if (err != Z_OK && err != Z_STREAM_END) { 1264 1264 if (err == Z_MEM_ERROR) throw std::bad_alloc(); 1265 1265 string msg = "inflate failed"; 1266 if ( inflate_zstream->msg) {1266 if (comp_stream.inflate_zstream->msg) { 1267 1267 msg += " ("; 1268 msg += inflate_zstream->msg;1268 msg += comp_stream.inflate_zstream->msg; 1269 1269 msg += ')'; 1270 1270 } 1271 1271 throw Xapian::DatabaseError(msg); 1272 1272 } 1273 1273 1274 1274 utag.append(reinterpret_cast<const char *>(buf), 1275 inflate_zstream->next_out - buf);1275 comp_stream.inflate_zstream->next_out - buf); 1276 1276 } 1277 if (utag.size() != inflate_zstream->total_out) {1277 if (utag.size() != comp_stream.inflate_zstream->total_out) { 1278 1278 string msg = "compressed tag didn't expand to the expected size: "; 1279 1279 msg += str(utag.size()); 1280 1280 msg += " != "; 1281 1281 // OpenBSD's zlib.h uses off_t instead of uLong for total_out. 1282 msg += str((size_t) inflate_zstream->total_out);1282 msg += str((size_t)comp_stream.inflate_zstream->total_out); 1283 1283 throw Xapian::DatabaseCorruptError(msg); 1284 1284 } 1285 1285 … … BrassTable::BrassTable(const char * tablename_, const string & path_, 1566 1566 cursor_version(0), 1567 1567 split_p(0), 1568 1568 compress_strategy(compress_strategy_), 1569 deflate_zstream(NULL), 1570 inflate_zstream(NULL), 1569 comp_stream(compress_strategy_), 1571 1570 lazy(lazy_) 1572 1571 { 1573 1572 LOGCALL_CTOR(DB, "BrassTable", tablename_ | path_ | readonly_ | compress_strategy_ | lazy_); … … BrassTable::really_empty() const 1587 1586 return !cur.next(); 1588 1587 } 1589 1588 1590 void1591 BrassTable::lazy_alloc_deflate_zstream() const {1592 if (usual(deflate_zstream)) {1593 if (usual(deflateReset(deflate_zstream) == Z_OK)) return;1594 // Try to recover by deleting the stream and starting from scratch.1595 delete deflate_zstream;1596 }1597 1598 deflate_zstream = new z_stream;1599 1600 deflate_zstream->zalloc = reinterpret_cast<alloc_func>(0);1601 deflate_zstream->zfree = reinterpret_cast<free_func>(0);1602 deflate_zstream->opaque = (voidpf)0;1603 1604 // -15 means raw deflate with 32K LZ77 window (largest)1605 // memLevel 9 is the highest (8 is default)1606 int err;1607 err = deflateInit2(deflate_zstream, Z_DEFAULT_COMPRESSION, Z_DEFLATED,1608 -15, 9, compress_strategy);1609 if (rare(err != Z_OK)) {1610 if (err == Z_MEM_ERROR) {1611 delete deflate_zstream;1612 deflate_zstream = 0;1613 throw std::bad_alloc();1614 }1615 string msg = "deflateInit2 failed (";1616 if (deflate_zstream->msg) {1617 msg += deflate_zstream->msg;1618 } else {1619 msg += str(err);1620 }1621 msg += ')';1622 delete deflate_zstream;1623 deflate_zstream = 0;1624 throw Xapian::DatabaseError(msg);1625 }1626 }1627 1628 void1629 BrassTable::lazy_alloc_inflate_zstream() const {1630 if (usual(inflate_zstream)) {1631 if (usual(inflateReset(inflate_zstream) == Z_OK)) return;1632 // Try to recover by deleting the stream and starting from scratch.1633 delete inflate_zstream;1634 }1635 1636 inflate_zstream = new z_stream;1637 1638 inflate_zstream->zalloc = reinterpret_cast<alloc_func>(0);1639 inflate_zstream->zfree = reinterpret_cast<free_func>(0);1640 1641 inflate_zstream->next_in = Z_NULL;1642 inflate_zstream->avail_in = 0;1643 1644 int err = inflateInit2(inflate_zstream, -15);1645 if (rare(err != Z_OK)) {1646 if (err == Z_MEM_ERROR) {1647 delete inflate_zstream;1648 inflate_zstream = 0;1649 throw std::bad_alloc();1650 }1651 string msg = "inflateInit2 failed (";1652 if (inflate_zstream->msg) {1653 msg += inflate_zstream->msg;1654 } else {1655 msg += str(err);1656 }1657 msg += ')';1658 delete inflate_zstream;1659 inflate_zstream = 0;1660 throw Xapian::DatabaseError(msg);1661 }1662 }1663 1664 1589 bool 1665 1590 BrassTable::exists() const { 1666 1591 LOGCALL(DB, bool, "BrassTable::exists", NO_ARGS); … … BrassTable::create_and_open(unsigned int block_size_) 1728 1653 BrassTable::~BrassTable() { 1729 1654 LOGCALL_DTOR(DB, "BrassTable"); 1730 1655 BrassTable::close(); 1731 1732 if (deflate_zstream) {1733 // Errors which we care about have already been handled, so just ignore1734 // any which get returned here.1735 (void) deflateEnd(deflate_zstream);1736 delete deflate_zstream;1737 }1738 1739 if (inflate_zstream) {1740 // Errors which we care about have already been handled, so just ignore1741 // any which get returned here.1742 (void) inflateEnd(inflate_zstream);1743 delete inflate_zstream;1744 }1745 1656 } 1746 1657 1747 1658 void BrassTable::close(bool permanent) { … … BrassTable::commit(brass_revision_number_t revision, int changes_fd, 1895 1806 } 1896 1807 1897 1808 void 1898 BrassTable::write_changed_blocks(int changes_fd )1809 BrassTable::write_changed_blocks(int changes_fd, bool compressed) 1899 1810 { 1900 LOGCALL_VOID(DB, "BrassTable::write_changed_blocks", changes_fd );1811 LOGCALL_VOID(DB, "BrassTable::write_changed_blocks", changes_fd | compressed); 1901 1812 Assert(changes_fd >= 0); 1902 1813 if (handle < 0) return; 1903 1814 if (faked_root_block) return; … … BrassTable::write_changed_blocks(int changes_fd) 1906 1817 pack_uint(buf, 2u); // Indicate the item is a list of blocks 1907 1818 pack_string(buf, tablename); 1908 1819 pack_uint(buf, block_size); 1909 io_write(changes_fd, buf.data(), buf.size());1910 1820 1821 // Write the table name and block size to the file 1822 io_write(changes_fd, buf.data(), buf.size()); 1823 1911 1824 // Compare the old and new bitmaps to find blocks which have changed, and 1912 1825 // write them to the file descriptor. 1913 1826 uint4 n = 0; … … BrassTable::write_changed_blocks(int changes_fd) 1917 1830 while (base.find_changed_block(&n)) { 1918 1831 buf.resize(0); 1919 1832 pack_uint(buf, n + 1); 1833 // Write the block number to the file 1920 1834 io_write(changes_fd, buf.data(), buf.size()); 1921 1835 1922 1836 // Read block n. 1923 1837 read_block(n, p); 1924 1838 1925 1839 // Write block n to the file. 1926 io_write(changes_fd, reinterpret_cast<const char *>(p), block_size); 1840 if (compressed) { 1841 comp_stream.lazy_alloc_deflate_zstream(); 1842 comp_stream.compress(p, block_size); 1843 if (comp_stream.zerr == Z_STREAM_END) { 1844 buf.resize(0); 1845 pack_uint(buf, comp_stream.deflate_zstream->total_out); 1846 io_write(changes_fd, buf.data(), buf.size()); 1847 io_write(changes_fd, reinterpret_cast<const char *>(comp_stream.out), 1848 comp_stream.deflate_zstream->total_out); 1849 } else { 1850 // The deflate failed, try to write data uncompressed 1851 buf.resize(0); 1852 pack_uint(buf, 0u); 1853 io_write(changes_fd, buf.data(), buf.size()); 1854 io_write(changes_fd, reinterpret_cast<const char *>(p), block_size); 1855 } 1856 } 1857 else { 1858 buf.resize(0); 1859 pack_uint(buf, 0u); 1860 io_write(changes_fd, buf.data(), buf.size()); 1861 io_write(changes_fd, reinterpret_cast<const char *>(p), block_size); 1862 } 1927 1863 ++n; 1928 1864 } 1929 1865 delete[] p; … … BrassTable::write_changed_blocks(int changes_fd) 1934 1870 } 1935 1871 buf.resize(0); 1936 1872 pack_uint(buf, 0u); 1873 // Write 0 for end of blocks 1937 1874 io_write(changes_fd, buf.data(), buf.size()); 1938 1875 } 1939 1876 -
xapian-core/backends/brass/brass_table.h
diff --git a/xapian-core/backends/brass/brass_table.h b/xapian-core/backends/brass/brass_table.h index 86c92a8..a51df2f 100644
a b 36 36 #include "stringutils.h" 37 37 #include "unaligned.h" 38 38 39 #include "common/zlib_utils.h" 40 39 41 #include <algorithm> 40 42 #include <string> 41 43 42 #include <zlib.h>43 44 44 #define DONT_COMPRESS -1 45 45 46 46 /** Even for items of at maximum size, it must be possible to get this number of … … class BrassTable { 406 406 * 407 407 * @param changes_fd The file descriptor to write changes to. 408 408 */ 409 void write_changed_blocks(int changes_fd );409 void write_changed_blocks(int changes_fd, bool compressed); 410 410 411 411 /** Cancel any outstanding changes. 412 412 * … … class BrassTable { 649 649 /// The name of the table (used when writing changesets). 650 650 const char * tablename; 651 651 652 /// Allocate the zstream for deflating, if not already allocated.653 void lazy_alloc_deflate_zstream() const;654 655 /// Allocate the zstream for inflating, if not already allocated.656 void lazy_alloc_inflate_zstream() const;657 652 658 653 /** revision number of the opened B-tree. */ 659 654 brass_revision_number_t revision_number; … … class BrassTable { 784 779 /** DONT_COMPRESS or Z_DEFAULT_STRATEGY, Z_FILTERED, Z_HUFFMAN_ONLY, 785 780 * Z_RLE. */ 786 781 int compress_strategy; 787 788 /// Zlib state object for deflating 789 mutable z_stream *deflate_zstream; 790 791 /// Zlib state object for inflating 792 mutable z_stream *inflate_zstream; 782 783 CompressionStream comp_stream; 793 784 794 785 /// If true, don't create the table until it's needed. 795 786 bool lazy; -
xapian-core/common/Makefile.mk
diff --git a/xapian-core/common/Makefile.mk b/xapian-core/common/Makefile.mk index 8865242..0211f8a 100644
a b noinst_HEADERS +=\ 37 37 common/str.h\ 38 38 common/stringutils.h\ 39 39 common/submatch.h\ 40 common/unaligned.h\ 41 common/zlib_utils.h 40 42 common/unaligned.h 41 43 44 42 45 EXTRA_DIST +=\ 43 46 common/dir_contents\ 44 47 common/win32_uuid.cc\ … … lib_src +=\ 59 62 common/serialise-double.cc\ 60 63 common/socket_utils.cc\ 61 64 common/str.cc\ 62 common/stringutils.cc 65 common/stringutils.cc\ 66 common/zlib_utils.cc 67 63 68 64 69 if USE_WIN32_UUID_API 65 70 lib_src +=\ -
new file xapian-core/common/zlib_utils.cc
diff --git a/xapian-core/common/zlib_utils.cc b/xapian-core/common/zlib_utils.cc new file mode 100644 index 0000000..8761f48
- + 1 #include <config.h> 2 3 #include "zlib_utils.h" 4 #include "str.h" 5 #include "stringutils.h" 6 7 CompressionStream::CompressionStream(int compress_strategy_) 8 : compress_strategy(compress_strategy_), 9 zerr(0), 10 out_len(0), 11 out(NULL), 12 deflate_zstream(NULL), 13 inflate_zstream(NULL) 14 { 15 // LOGCALL_CTOR() 16 } 17 18 CompressionStream::~CompressionStream() { 19 if (deflate_zstream) { 20 // Errors which we care about have already been handled, so just ignore 21 // any which get returned here. 22 (void) deflateEnd(deflate_zstream); 23 delete deflate_zstream; 24 } 25 26 if (inflate_zstream) { 27 // Errors which we care about have already been handled, so just ignore 28 // any which get returned here. 29 (void) inflateEnd(inflate_zstream); 30 delete inflate_zstream; 31 } 32 33 if (out) { 34 delete [] out; 35 } 36 } 37 38 39 void 40 CompressionStream::compress(string & buf) { 41 out_len = buf.size() - 1; 42 out = new unsigned char[out_len]; 43 deflate_zstream->avail_in = (uInt)buf.size(); 44 deflate_zstream->next_in = (Bytef *)const_cast<char *>(buf.data()); 45 deflate_zstream->next_out = out; 46 deflate_zstream->avail_out = (uInt)out_len; 47 zerr = deflate(deflate_zstream, Z_FINISH); 48 } 49 50 51 void 52 CompressionStream::compress(byte * buf, int size) { 53 out_len = size - 1; 54 out = new unsigned char[out_len]; 55 deflate_zstream->avail_in = (uInt)size; 56 deflate_zstream->next_in = (Bytef *)(buf); 57 deflate_zstream->next_out = out; 58 deflate_zstream->avail_out = (uInt)out_len; 59 zerr = deflate(deflate_zstream, Z_FINISH); 60 } 61 62 // void 63 // CompressionStream::decompress(string & buf) { 64 // inflate_zstream->next_in = (Bytef*)const_cast<char *>(tag->data()); 65 // inflate_zstream->avail_in = (uInt)tag->size(); 66 // int err = Z_OK; 67 // while (err != Z_STREAM_END) { 68 // comp_stream.inflate_zstream->next_out = buf; 69 // comp_stream.inflate_zstream->avail_out = (uInt)sizeof(buf); 70 // err = inflate(comp_stream.inflate_zstream, Z_SYNC_FLUSH); 71 // if (err == Z_BUF_ERROR && comp_stream.inflate_zstream->avail_in == 0) { 72 // LOGLINE(DB, "Z_BUF_ERROR - faking checksum of " << comp_stream.inflate_zstream->adler); 73 // Bytef header2[4]; 74 // setint4(header2, 0, comp_stream.inflate_zstream->adler); 75 // comp_stream.inflate_zstream->next_in = header2; 76 // comp_stream.inflate_zstream->avail_in = 4; 77 // err = inflate(comp_stream.inflate_zstream, Z_SYNC_FLUSH); 78 // if (err == Z_STREAM_END) break; 79 // } 80 81 // if (err != Z_OK && err != Z_STREAM_END) { 82 // if (err == Z_MEM_ERROR) throw std::bad_alloc(); 83 // string msg = "inflate failed"; 84 // if (comp_stream.inflate_zstream->msg) { 85 // msg += " ("; 86 // msg += comp_stream.inflate_zstream->msg; 87 // msg += ')'; 88 // } 89 // throw Xapian::DatabaseError(msg); 90 // } 91 92 // utag.append(reinterpret_cast<const char *>(buf), 93 // comp_stream.inflate_zstream->next_out - buf); 94 // } 95 // if (utag.size() != comp_stream.inflate_zstream->total_out) { 96 // string msg = "compressed tag didn't expand to the expected size: "; 97 // msg += str(utag.size()); 98 // msg += " != "; 99 // // OpenBSD's zlib.h uses off_t instead of uLong for total_out. 100 // msg += str((size_t)comp_stream.inflate_zstream->total_out); 101 // throw Xapian::DatabaseCorruptError(msg); 102 // } 103 // } 104 105 106 void 107 CompressionStream::lazy_alloc_deflate_zstream() const { 108 if (usual(deflate_zstream)) { 109 if (usual(deflateReset(deflate_zstream) == Z_OK)) return; 110 // Try to recover by deleting the stream and starting from scratch. 111 delete deflate_zstream; 112 } 113 114 deflate_zstream = new z_stream; 115 116 deflate_zstream->zalloc = reinterpret_cast<alloc_func>(0); 117 deflate_zstream->zfree = reinterpret_cast<free_func>(0); 118 deflate_zstream->opaque = (voidpf)0; 119 120 // -15 means raw deflate with 32K LZ77 window (largest) 121 // memLevel 9 is the highest (8 is default) 122 int err; 123 // FIXME:dc: this needs to really use compress_strategy if set 124 err = deflateInit2(deflate_zstream, Z_DEFAULT_COMPRESSION, Z_DEFLATED, 125 -15, 9, Z_DEFAULT_STRATEGY); 126 if (rare(err != Z_OK)) { 127 if (err == Z_MEM_ERROR) { 128 delete deflate_zstream; 129 deflate_zstream = 0; 130 throw std::bad_alloc(); 131 } 132 string msg = "deflateInit2 failed ("; 133 if (deflate_zstream->msg) { 134 msg += deflate_zstream->msg; 135 } else { 136 msg += str(err); 137 } 138 msg += ')'; 139 delete deflate_zstream; 140 deflate_zstream = 0; 141 throw Xapian::DatabaseError(msg); 142 } 143 } 144 145 void 146 CompressionStream::lazy_alloc_inflate_zstream() const { 147 if (usual(inflate_zstream)) { 148 if (usual(inflateReset(inflate_zstream) == Z_OK)) return; 149 // Try to recover by deleting the stream and starting from scratch. 150 delete inflate_zstream; 151 } 152 153 inflate_zstream = new z_stream; 154 155 inflate_zstream->zalloc = reinterpret_cast<alloc_func>(0); 156 inflate_zstream->zfree = reinterpret_cast<free_func>(0); 157 158 inflate_zstream->next_in = Z_NULL; 159 inflate_zstream->avail_in = 0; 160 161 int err = inflateInit2(inflate_zstream, -15); 162 if (rare(err != Z_OK)) { 163 if (err == Z_MEM_ERROR) { 164 delete inflate_zstream; 165 inflate_zstream = 0; 166 throw std::bad_alloc(); 167 } 168 string msg = "inflateInit2 failed ("; 169 if (inflate_zstream->msg) { 170 msg += inflate_zstream->msg; 171 } else { 172 msg += str(err); 173 } 174 msg += ')'; 175 delete inflate_zstream; 176 inflate_zstream = 0; 177 throw Xapian::DatabaseError(msg); 178 } 179 } -
new file xapian-core/common/zlib_utils.h
diff --git a/xapian-core/common/zlib_utils.h b/xapian-core/common/zlib_utils.h new file mode 100644 index 0000000..6fbcee8
- + 1 #ifndef XAPIAN_INCLUDED_ZLIB_UTILS_H 2 #define XAPIAN_INCLUDED_ZLIB_UTILS_H 3 4 #include "debuglog.h" 5 6 #include "internaltypes.h" 7 8 #include "xapian/error.h" 9 10 #include <zlib.h> 11 12 using namespace std; 13 14 #define DONT_COMPRESS -1 15 16 class CompressionStream { 17 18 public: 19 CompressionStream(int); 20 21 ~CompressionStream(); 22 23 int compress_strategy; 24 25 int zerr; 26 27 unsigned long out_len; 28 29 unsigned char * out; 30 31 /// Zlib state object for deflating 32 mutable z_stream *deflate_zstream; 33 34 /// Zlib state object for inflating 35 mutable z_stream *inflate_zstream; 36 37 /// Allocate the zstream for deflating, if not already allocated. 38 void lazy_alloc_deflate_zstream() const; 39 40 /// Allocate the zstream for inflating, if not already allocated. 41 void lazy_alloc_inflate_zstream() const; 42 43 void compress(string &); 44 void compress(byte *, int); 45 }; 46 47 #endif // XAPIAN_INCLUDED_ZLIB_UTILS_H -
xapian-core/tests/api_query.cc
diff --git a/xapian-core/tests/api_query.cc b/xapian-core/tests/api_query.cc index 0d8a8e2..64bd6c9 100644
a b DEFINE_TESTCASE(overload1, !backend) { 66 66 Xapian::Query q; 67 67 q = Xapian::Query("foo") & Xapian::Query("bar"); 68 68 TEST_STRINGS_EQUAL(q.get_description(), "Query((foo AND bar))"); 69 q = Xapian::Query("foo") & ~ Xapian::Query("bar");69 q = Xapian::Query("foo") & (~Xapian::Query("bar")); 70 70 TEST_STRINGS_EQUAL(q.get_description(), "Query((foo AND_NOT bar))"); 71 71 q = ~Xapian::Query("bar"); 72 72 TEST_STRINGS_EQUAL(q.get_description(), "Query((<alldocuments> AND_NOT bar))");